• Код што е ефтин за оддржување • Код што нема да бара многу ресурси (време и луѓе) за проширување • Код што е близок до човековото сфаќање за материјалниот свет Прашањето е: КАКО да пишуваме таков код?
• Секоја класа/модул/метод мора да има само една одговорност (или задача). • Секоја класа/модул/метод мора во целост да ја извршува таа одговорност. ◦ Не смее да има “скриена” имплементација. • Целта е да создаде кохезија помеѓу класите, но секоја класа да има своја единствена одговорност.
класа мора да биде отворена за проширување/надоградување но мора да биде затворена за модификација. Овој принцип може да се имплементира преку наследување: • Meyer’s Open/closed principle ◦ Баг-фикс е ОК ◦ Новa/промена на функционалност -> нова дете класа • Polymorphic Open/closed principle ◦ Абстрактен интерфејс/класа ◦ Менување на имплементации преку полиморфизам
Gamma, Richard Helm, Ralph Johnson, John Vlissides. Наместо да се користи наследување, подобро е да се користи композиција на објектите. Чисто инфомативно, pattern-от што е искористен во примерот е Dependency Injection.
Барбара Лисков вели: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T. Доколку постои класа Б, која е дете-класа на класата А и класа В, која има исто однесување (ист интерфејс) како класата Б, тоа имплицира дека класата Б и класата В се исти, односно, деца на иста класа и можат да бидат заменети.
тесно поврзано со пристапот наречен design by contract. ◦ Дизајнерите треба да имаат формален и прецизен начин на дефинирање на интерфејсите на класите. • Ruby како динамички јазик по дифолт го поддржува овој принцип. • Ова е добро познато како duck typing. ◦ In duck typing, a programmer is only concerned with ensuring that objects behave as demanded of them in a given context, rather than ensuring that they are of a specific type. “When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.” - James Whitcomb Riley
Дефиниција: еден клиент не треба да биде приморан да зависи од методи кои што не ги користи. Кога клиент А (класа/модул) зависи од класа која содржи интерфејси (најчесто методи) кои што клиентот А не ги користи, но други клиенти ги користат, тогаш промените кои остантите клиенти ги форсираат врз класата ќе влијаат и врз клиентот А.
Дефиниција: компонентите во софтверот треба да зависат од абстракции наместо имплементации. • Руби овој проблем го решава со самото тоа што поддржува duck-typing. Проблемот е увиден во Јава, а решен преку интерфејси. • Една класа не треба да ја интересира имплементацијата на некој објект, туку само интерфејсот на истиот преку кој што може да испраќа пораки односно наредби.
Често за имплементирање на DPI се користи Dependency Injection шаблонот (pattern). • Wikipedia: Dependency injection is a software design pattern in which one or more dependencies are injected, or passed by reference, into a dependent object and are made part of the client's state. The pattern separates the creation of a client's dependencies from its own behavior, which allows program designs to be loosely coupled and to follow the dependency inversion and single responsibility principles. • Постојат повеќе типови на Dependency Injection. ◦ Constructor Injection ◦ Setter Injection ◦ Interface Injection
за добар ОО дизајн кој што може да трпи големи промени, а веќе постоечката функционалност да претрпи мали (или никакви) промени • треба добро да се сфати поентата на истите и како тие можат да го подобрат кодот • треба добро познавање на принципите за да може интуитивно и секојдневно да се применуваат • Лоши страни? Стварно незнам. Можеби комплексноста?