Когда вы разрабатываете программное обеспечение, вы всегда должны балансировать между разными принципами, потому что многие из них противоречат друг другу. Например, принцип DRY (не повторяйся) часто противоречит принципу единой ответственности, особенно когда две вещи действуют одинаково, но не в точности одно и то же.
Часто вам приходится решать, какой принцип более важен, и делать упор на этом принципе над другим (хотя вы должны стараться придерживаться как можно большего числа). Часто принципы работают вместе, иногда они работают друг против друга.
В этом случае «Скажи, не спрашивай» работает с другими принципами, такими как Закон Деметры (который, несмотря на свое название, все еще принцип в отношении программного обеспечения, и его лучше описать как принцип наименьшего знания).
LoD сообщает нам, что метод объекта должен вызывать только другие методы.
- На себе
- Об объектах, переданных в него в качестве параметра
- Любые объекты, созданные / экземпляры с объектом, переданным параметром
- объекты направляют объекты компонентов
- Или глобальная переменная
Это специально не сказано, но я считаю, что порядок предпочтения выбора методов для вызова также должен быть в этом порядке, с глобальными переменными в крайнем случае. Но это ни здесь, ни там.
Итак, если мы объединим «Скажи, не спрашивай» с LoD, тогда совершенно нормально передавать объекты другому объекту для «запроса». Это означает, что у вас есть объект анализа, которому вы «говорите» что-то делать, передавая объект DataSet в качестве параметра. Это придерживается TDA. Внутри метода объекта Analysis вы придерживаетесь LoD, обращаясь только к данным «близких друзей».
Это также соответствует SRP, поскольку ваш DataSet по-прежнему является просто DataSet, а ваш объект Analysis является объектом Analysis.
Ключевой вывод здесь состоит в том, что эти принципы часто являются «релятивистскими». Это означает, что с точки зрения родительского объекта, который получает данные и хочет выполнить анализ, вы «говорите» объекту анализа что-то сделать.
Цель TDA состоит в том, чтобы ваш родительский код не запрашивал ваш DataSet о его состоянии, а затем принимал решения на основе этого. Вместо этого он должен передавать объекты другим объектам и заставлять эти объекты выполнять свои обязанности, которые могут включать в себя запросы этих объектов на предмет их состояния, но это нормально, потому что это в контексте их ответственности.
Дополнительная ссылка здесь:
http://pragprog.com/articles/tell-dont-ask
РЕДАКТИРОВАТЬ:
Если вам нужен более авторитетный источник, нет никого лучше, чем сам Мартин Фаулер (прочтите в конце, вы найдете этот комментарий)
http://martinfowler.com/bliki/TellDontAsk.html
Но лично я не использую «скажи, не спрашивай». Я стараюсь объединить данные и поведение, что часто приводит к схожим результатам. Одна вещь, которая меня беспокоит в отношении «скажи-не-спрашивай», - это то, что я видел, как он побуждает людей становиться GetterEradicators, стремясь избавиться от всех методов запросов. Но бывают случаи, когда объекты эффективно взаимодействуют, предоставляя информацию. Хорошим примером являются объекты, которые принимают входную информацию и преобразуют ее для упрощения работы своих клиентов, например с помощью EmbeddedDocument. Я видел, как код зацикливался, говоря только о том, где подходящие методы запроса упростят задачу 1. Для меня «скажи-не-спрашивай» - это ступенька к совмещению поведения и данных, но я не считаю, что это стоит особо выделять.
person
Erik Funkenbusch
schedule
05.06.2014