2010-11-23 7 views
1

Коллега мой, как правило, проектировать классы, как:Где я могу найти краткий, хорошо написанный аргумент против этой инициализации анти-шаблона и, возможно, других?

class ImportantClass 
{ 
    public SomeClass ImportantField; 
    public SomeOtherClass OtherImportantField; 
    // etc. 
} 

Он не будет писать не конструктор. Тогда, где он конкретизирует этот тип его код будет выглядеть следующим образом:

ImportantClass x; 

try 
{ 
    // This is problematic enough to begin with, as every field (which is public) 
    // is set manually, which causes code duplication wherever this type is 
    // instantiated as well as maintenance problems in the event new fields are 
    // introduced or internal implementation is changed. 
    x = new ImportantClass(); 
    x.ImportantField = new SomeClass(); 
    x.OtherImportantField = new SomeOtherClass(); 
} 
catch (Exception ex) 
{ 
    // ...what's even worse: now x can easily be in a totally invalid state, 
    // with some fields initialized and some not. 
    HandleAnyException(ex); 
} 

Очевидно, что выше является упрощенным (и преувеличено) пример; но я думаю, вы понимаете.

Я не публикую это, чтобы критиковать моего коллегу; скорее, я хочу найти для него множество проблем в развитии таких классов и указать ему в правильном направлении. Я лично считаю, что этот дизайн, в то время как довольно бедный, является тем, что легко «исправлено».

Моя главная задача в том, что , если я хочу, чтобы убедить его, что будет важно для меня, чтобы иметь аргумент, который является сильным (хорошо поддерживается), легко понять, и кратким (он не будет хотеть прочитайте 2-страничное электронное письмо с сообщением, почему я думаю, что его код должен измениться).

Есть ли хорошие ресурсы, которые обеспечивают такие хорошо продуманные аргументы, устраняя недостатки этого и, возможно, других недобросовестных анти-шаблонов дизайна? Что-то вроде компендиума «ошибок в распространении программного обеспечения» было бы чрезвычайно полезно, если оно существует.

Примечание: Я понимаю, что просто говорить об этом является самым прямым и, возможно, наименее разрушительным способом дать совет; Я просто думаю, было бы неплохо также иметь этот ресурс, который я могу указать как ссылку, опять же, если такой ресурс существует.

+1

Ничего себе. Они платят ему писать такие вещи? –

ответ

2

Нарушает принципы ответственности. Если ImportantClass нуждается в двух других экземплярах для правильной работы, то это должно быть ImportantClass, чтобы убедиться, что они находятся в известном хорошем состоянии, прежде чем что-либо еще произойдет.

2

Этот код нарушает несколько принципов, описанных в превосходной книге «Эффективная Java» Джошуа Блоха, которую я очень рекомендую. Так, например, на общественных полях экземпляра:

Если поле экземпляра не является окончательным, или является окончательной ссылкой на изменяемый объекта, а затем, сделав поле общественности, вы отказываетесь способностью к ограничьте значения, которые можно сохранить в поле . Это означает, что вы также отказываетесь от возможности принудительного применения инвариантов , связанных с этим полем. Кроме того, вы отказываетесь от возможность принимать какие-либо действия при изменении , поэтому классы с общедоступными изменяемыми полями не являются потокобезопасными. Даже если поле является окончательным и относится к неизменяемому объекту, то , в результате чего вы публикуете , гибкость для перехода на новое внутреннее представление данных , в котором это поле не существует.

Кроме того, вы не достигаете инкапсуляции с этими полями.

В книге есть что сказать о том, как сделать инициализацию объекта безопасно и правильно.Достаточно сказать, что код, который вы опубликовали, очень проблематичен.

1

Вы можете упомянуть ему, что этот подход кодирования нарушает одну из трех основных концепций объектно-ориентированного развития, которая, конечно же, является инкапсуляцией.

Тот факт, что состояние его объекта может быть изменен непосредственно его пользователями, что делает отладку очень трудно, в отличие от частного метода, который будет единственным способом получить доступ к внутренним данным ...

Более того , его клиенты тесно связаны со своим классом, поэтому в случае, когда он хочет внести некоторые внутренние изменения, его клиенты должны быть перекомпилированы, несмотря на тот факт, что произошедшие изменения не повлияли на их использование ....

Правда, правда , заключается в том, что в последние годы применение инкапсуляции данных в OO-системах было ослаблено по сравнению с прошлым.

Такие технологии, как SPRING или LINQ, например, прямо нарушают конфиденциальность сведений о реализации, пытаясь архивировать поведение IOC или «как функциональное».

Прямое следствие этой тенденции является недавним принятием от C# автоматических свойств, которые используются для упрощения прямого воздействия частных данных, как установить/получить свойство ...

1

Это нарушает Principle of Least Astonishment потому как потребитель класс I потребует рабочих знаний класса, чтобы он работал без исключений (или запускал его, пока не получаю исключений, которые были бы огромной болью в a $$).

Некоторые цитаты из http://portal.acm.org/citation.cfm?id=1176622:

API, должны быть простыми в использовании и трудно неправильного использования. Легко делать простые вещи; возможно делать сложные вещи; и невозможно, или, по крайней мере, трудно, делать неправильные вещи.

Храните API без сведений о реализации. Они путают пользователей и препятствуют развитию гибкости. Не всегда очевидно, что представляет собой деталь реализации: будьте осторожны с чрезмерной спецификацией.

 Смежные вопросы

  • Нет связанных вопросов^_^