Ну, я начинаю думать, что нужен прагматичный подход к каждой проблеме, а не просто подписываться на архитектурные стандарты пуриста.
Чем меньше зависимостей у вас есть между Model, View и Controller, тем проще будет сделать это изменения в DomainModel, не нарушая контрактов интерфейса в представлении и контроллере и т. д. и т. д. Но опять-таки это будет что-то прагматичное. Мне нравится подход, поскольку перефакторинг кода является большой частью системного обслуживания - рефакторинг может включать в себя простую орфографическую ошибку для свойства модели - это изменение может пульсировать через код до уровня Контракта, если зависимости не разделены; например.
Простой пример datetime, хранящийся в Informix, должен быть переведены в .Net DateTime. ViewModel - идеальное место для этого перевода и не заставляет вас вводить код перевода во всевозможные нежелательные места.
Одним из атрибутов хорошей конструкции [чего-либо] является возможность замены или изменения часть реализации с небольшим или никаким воздействием на остальные части системы. Но это требует усилий и времени для достижения - вам решать найти практический баланс между идеальным дизайном и дизайном , который достаточно
Но да, есть много других оснований для использования определенных шаблонов, но в нижней строке это:
Ничто не заставляет вас использовать ViewModels ... ASP.NET MVC не заставит вас. Возьмите совет у прагматика внутри вас.
Они делают то же самое. Фактически, документы для распространения модулей Python были только что обновлены , предлагая использовать python -m pip
вместо исполняемого файла pip
, потому что легче сказать, какая версия python будет использоваться для фактического запуска pip
.
Изменить:
Вот еще несколько конкретных «доказательств», за исключением того, что я доверяю своему слову и отчет об ошибке, который я связал:)
Если вы посмотрите на исполняемый скрипт pip
, он просто делает это:
from pkg_resources import load_entry_point
<snip>
load_entry_point('pip==1.5.4', 'console_scripts', 'pip')()
Он вызывает load_entry_point
, который возвращает функцию, а затем выполняет это функция. Используемая точка входа называется 'console_scripts'
. Если вы посмотрите файл entry_points.txt для pip
(/usr/lib/python2.7/dist-packages/pip-1.5.4.egg-info/entry_points.txt на моей машине Ubuntu), вы увидите это:
[console_scripts]
pip = pip:main
pip2.7 = pip:main
pip2 = pip:main
Таким образом, возвращаемая точка входа является функцией main
в модуле pip
.
Когда вы запускаете python -m pip
, вы выполняете __main__.py
внутри пакета pip
. Это выглядит так:
import sys
from .runner import run
if __name__ == '__main__':
exit = run()
if exit:
sys.exit(exit)
И функция runner.run
выглядит так:
def run():
base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
## FIXME: this is kind of crude; if we could create a fake pip
## module, then exec into it and update pip.__path__ properly, we
## wouldn't have to update sys.path:
sys.path.insert(0, base)
import pip
return pip.main()
Как вы можете видеть, это просто вызывает функцию pip.main
, тоже , Таким образом, обе команды в конечном итоге вызывают одну и ту же функцию main
в pip/__init__.py
.
pip
, но и к другим инструментам командной строки Python & quot; можно назвать так. Например,python -m markdown
. Чтобы указать из меню справки python-m mod : run library module as a script
– Sebastian 9 September 2014 в 21:57python -m pip
запускает модульpip/__main__.py
, а неpip/__init__.py
. Это общее правило:python -m module
запускает модульmodule.__main__
, еслиmodule
является пакетом (имеет атрибут__path__
), иначе он запускает самmodule
- оба с__name__=="__main__"
. – jfs 9 September 2014 в 22:10