Програмування твердих принципів


43

З часом я міг зрозуміти дві частини SOLID - "S" і "O".

«О» - Я навчився принципу відкритого закритого типу за допомогою структури спадкування та стратегії.

“S” - я засвоїв принцип єдиної відповідальності під час вивчення ORM (логіка стійкості забирається з об’єктів домену).

Аналогічним чином, які найкращі регіони / завдання вивчити інші частини SOLID (“L”, “I” та “D”)?

Список літератури

  1. msdn - Небезпеки порушення принципів твердих речовин у C #
  2. channel9 - Застосування твердих принципів у .NET / C #
  3. Принципи OOPS (тверді принципи)

25
зауважте, що всі ці ідеї - це хороші ідеї, і разом вони дуже хороші. але якщо застосувати їх догматично, вони спричинить більше невдач, ніж успіху.

3
АБО-картографи добре підходять для роз'єднання проблем, а не єдиного принципу відповідальності. Дивіться цю публікацію programmers.stackexchange.com/questions/155628/… для обговорення відмінностей.
Doc Brown

Приклади реального світу blog.gauffin.org/2012/05/…
LCJ

1
@JarrodRoberson Так, саме тому їх ретельно називають вказівками . Також не забувайте про інші принципи: adamjamesnaylor.com/2012/11/12/… (всього 11)
Адам Нейлор

2
Посилання @AdamNaylor зараз 404ing, його перенесли на adamjamesnaylor.com/post/…
mattumotu

Відповіді:


54

Я був у вашому взутті пару місяців тому, поки не знайшов дуже корисну статтю.

Кожен принцип чудово пояснюється ситуаціями в реальному світі, з якими може стикатися кожен розробник програмного забезпечення у своїх проектах. Я коротко кажу про це і вказую на посилання - SOLID Software Development, один крок за часом .

Як зазначається в коментарях, є ще одне дуже хороше читання у форматі PDF - розробка програмного забезпечення SOLID Software Pablo .

Крім того, є кілька хороших книг, які детальніше описують принципи SOLID - Хороша книга про розробку програмного забезпечення SOLID .

Редагуйте та коментуйте короткий підсумок для кожного принципу:

  • "S" - Принцип єдиної відповідальності визначається потребами бізнесу, щоб дозволити зміни. "Єдина причина змінити" допомагає зрозуміти, які логічно окремі поняття слід об'єднати, розглядаючи бізнес-концепцію та контекст, а не технічну концепцію. In another words, я дізнався, що кожен клас повинен нести єдину відповідальність. Відповідальність полягає в тому, щоб просто виконати поставлене завдання

  • “O” - я навчився принципу відкритого закритого типу і почав “віддавати перевагу композиції над успадкуванням” і, таким чином, віддав перевагу класам, які не мають віртуальних методів і, можливо, запечатані, але залежать від абстракцій для їх розширення.

  • “L” - Я дізнався Принцип заміщення Ліскова за допомогою шаблону сховища для управління доступом до даних.

  • "Я" - Я дізнався про принцип розбиття інтерфейсів, дізнавшись, що клієнтів не слід змушувати впроваджувати інтерфейси, які вони не використовують (як, наприклад, в членському провайдері в ASP.NET 2.0). Тому інтерфейс не повинен мати "багато обов'язків"
  • "D" - Я дізнався про принцип інверсії залежності і почав кодувати, що легко змінити . Легше змінити означає меншу загальну вартість володіння та більш високу ремонтопридатність.

Оскільки в коментарях згадувався корисний ресурс від CodePlex, посилання на SOLID міститься на прикладі

введіть тут опис зображення


3
Наступна колекція статей мені
здалася

Я прочитав всю цю статтю, і мене не продають на шаблонах чи на SOLID. Приклад занадто спрощений, але коли він стає складним, ця складність є штучною. Мені ще належить зіткнутися з реальним світом SOLID OOP без кращих альтернатив.
робота

3
оскільки тут згадуються статті про лостехії, є також цей soliddexamples.codeplex.com (на основі lostechies)
темний фейдер

2
Я був одним із учасників електронної книги Pablos. Я радий, що люди все ще вважають це корисним. :)
Шон Чемберс

1
+1000000, якщо я міг би зробити ваш підсумок принципу відкритого закриття - всі помиляються і думають, що йдеться про спадщину
AlexFoxGill

11

(I) поділ між поверхнями та інверсія випромінювання (D) можна дізнатися за допомогою тестування блоків та знущань. Якщо класи створюють власні залежності, ви не можете створити хороші одиничні тести. Якщо вони залежать від занадто широкого інтерфейсу (або взагалі відсутній інтерфейс), не дуже очевидно, що потрібно знущатись, щоб зробити ваші одиничні тести.


2
+1 це дуже правда. Вам навіть не доведеться дотримуватися (imo) іноді занадто суворого правила «одиничний тест повинен перевірити лише одне»: якщо ви не можете придумати гідний тестовий набір для класу за пару хвилин, це порушує I і D, і, мабуть, і решту
альфабету

8

Принцип заміщення Ліскова в основному не дозволяє вам зловживати успадкуванням реалізації: ніколи не слід використовувати спадщину лише для повторного використання коду (для цього є склад)! Дотримуючись LSP, ви можете бути впевнені в тому, що між вашим суперкласом та вашим підкласом існує фактично "співвідношення".

Це говорить про те, що ваші підкласи повинні реалізовувати всі методи підкласу аналогічно до реалізації методів у підкласі. Ніколи не слід перекривати метод із реалізацією NOP або повертати null, коли супертип викидає виняток; зазначені в Дизайні за умовами контракту, ви повинні дотримуватись контракту методу з надкласового класу, коли замінюєте метод. Спосіб захисту від порушення цього принципу - ніколи не відміняючи реалізований метод; замість цього витягніть інтерфейс і реалізуйте цей інтерфейс в обох класах.

Принцип поділу інтерфейсу, Принцип єдиної відповідальності та Принцип високої когезії від GRASP так чи інакше пов'язані; вони посилаються на той факт, що суб'єкт господарювання повинен відповідати лише за одне, так що існує лише одна причина змін, так що зміни відбуваються дуже легко.

Насправді йдеться про те, що якщо клас реалізує інтерфейс, він повинен реалізувати та використовувати всі методи цих інтерфейсів. Якщо в цьому конкретному класі є методи, які не потрібні, то інтерфейс не є хорошим і повинен бути розділений на два інтерфейси, у яких є лише методи, необхідні для початкового класу. Це можна вважати з POV, що стосується попереднього принципу тим, що він не дозволяє створювати великі інтерфейси, щоб їх реалізація могла зламати LSP.

Ви можете побачити інверсію залежності в заводській схемі; тут і компонент високого рівня (клієнт), і компонент низького рівня (окремий екземпляр, який слід створити) залежать від абстракції(інтерфейс). Спосіб застосування його в шаруватій архітектурі: не слід визначати інтерфейс для шару в шарі, який реалізується, а в модулі, який викликається. Наприклад, API до рівня джерела даних не повинен записуватися в рівень джерела даних, а в рівень логіки buisness, куди потрібно викликати. Таким чином, рівень джерела даних успадковує / залежить від поведінки, визначеної в логіці buisness (таким чином, інверсії), а не навпаки (як це було б у звичайному порядку). Це забезпечує гнучкість у дизайні, що дозволяє бізнес-логіці працювати без будь-якої зміни коду, з іншим зовсім іншим джерелом даних.


1
Чудове пояснення Ліскову. :)
Джон Корнес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.