Я не согласен с вашим заключением. Существует много хороших способов инкапсуляции в C# со всеми вышеупомянутыми технологиями, чтобы поддерживать хорошие методы кодирования программного обеспечения. Я бы также сказал, что это зависит от того, на чью технологическую демонстрацию вы смотрите, но в конце концов это сводится к уменьшению пространства состояний ваших объектов, чтобы вы могли убедиться, что они всегда сохраняют свои инварианты.
Возьмите объект реляционных фреймворков; большинство из них позволяют вам указать, как они собираются увлажнять объекты; NHibernate, например, позволяет так сказать access="property"
или access="field.camelcase"
и тому подобное. Это позволяет вам инкапсулировать ваши свойства.
Зависимость впрыска работает с другими типами, которые у вас есть, в основном те, которые не являются сущностями, даже если вы можете комбинировать AOP + ORM + IOC в некоторых очень хороших способах улучшить состояние этих вещей. IoC часто используется из слоев над вашими сущностями домена, если вы создаете приложение, управляемое данными, которое, как я полагаю, есть, поскольку вы говорите об ORM.
Они («они» являются приложениями и службами домена и другими внутренними классами для программы) раскрывают свои зависимости, но на самом деле могут быть инкапсулированы и протестированы в еще лучшей изоляции, чем раньше, поскольку парадигмы проектирования по контракту/дизайну -by-interface, который вы часто используете при издевательских зависимостях при макетировании (в сочетании с IoC), переместит вас к семантике класса-компонента. Я имею в виду: каждый класс, созданный с использованием вышеизложенного, будет лучше инкапсулирован.
Обновлено для Urig: Это справедливо для обоих обнажая конкретных зависимостей и обнажая интерфейсов. Сначала о интерфейсах. То, что я намекал выше, заключалось в том, что сервисы и другие классы приложений, которые имеют зависимости, могут с ООП зависеть от контрактов/интерфейсов, а не от конкретных реализаций. В языках C/C++ и более старых языках не было интерфейса, и абстрактные классы могли только зайти. Интерфейсы позволяют связать разные экземпляры среды выполнения с одним и тем же интерфейсом, не беспокоясь о утечке внутреннего состояния, из-за которого вы пытаетесь уйти от абстрагирования и инкапсуляции. С абстрактными классами вы все равно можете обеспечить реализацию класса, просто вы не можете его создать, но наследникам все еще нужно знать об инвариантах в вашей реализации, и это может испортить состояние.
Во-вторых, о конкретных классах как свойствах: вы должны быть осторожны относительно того, какие типы типов;) вы раскрываете как свойства. Скажем, у вас есть список в вашем экземпляре; то не раскрывайте IList как свойство; это, вероятно, будет протекать, и вы не можете гарантировать, что потребители интерфейса не добавляют вещи или не удаляют вещи, от которых вы зависите; вместо этого выведите что-то вроде IEnumerable и верните копию списка или, что еще лучше, сделайте это как метод: public IEnumerable MyCollection {get {return _List.Enum(); }}, и вы можете быть на 100% уверенными, чтобы получить как производительность, так и инкапсуляцию. Никто не может добавлять или удалять этот IEnumerable, и вам все равно не нужно выполнять дорогостоящую копию массива. Соответствующий вспомогательный метод:
static class Ext {
public static IEnumerable<T> Enum<T>(this IEnumerable<T> inner) {
foreach (var item in inner) yield return item;
}
}
Таким образом, хотя вы не можете получить 100% герметизации, скажем, создающие перегружено равно операторы/метод, который вы можете получить рядом с вашими открытыми интерфейсами.
Вы также можете использовать новые функции .Net 4.0, построенные на SpeC#, чтобы проверить контракты, о которых я говорил выше.
Сериализация всегда будет там и была в течение длительного времени. Ранее до интернет-области он использовался для сохранения вашего графического объекта на диск для последующего извлечения, теперь он используется в веб-службах, в семантике копирования и при передаче данных, например. браузер. Это не обязательно разрушает инкапсуляцию, если вы поместите несколько атрибутов [NonSerialized] или эквиваленты в правильные поля.
Инициализаторы объектов не такие же, как конструкторы, это всего лишь способ свернуть несколько строк кода. Значения/экземпляры в {} не будут назначены до тех пор, пока все ваши конструкторы не будут запущены, поэтому в принципе это то же самое, что не использовать инициализаторы объектов.
Я полагаю, что вы должны следить за тем, чтобы отказаться от хороших принципов, которые вы узнали из своей предыдущей работы, и убедитесь, что ваши объекты домена заполнены бизнес-логикой, инкапсулированной за хорошие интерфейсы, а также для вашего обслуживания -слой.
Не позволяйте никому обмануть вас, эти инициализаторы объектов - это просто синтаксический сахар. – BobbyShaftoe
Я знаю, что инициализаторы объектов не являются конструкторами, но это не моя точка. Они позволяют создавать объект с использованием конструктора по умолчанию и задавать свойства вручную. –
Не совсем уверен, какая разница между ними и просто печатать каждое утверждение, чтобы установить каждое свойство. Но хорошо. – BobbyShaftoe