Изложен модел на дизайн: Стратегически модел



В този блог ще разкрием Шаблон за стратегически дизайн, който се използва за създаване на взаимозаменяемо семейство алгоритми, които могат да бъдат избирани динамично.

'

Добре дошли в първата публикация от поредицата „Изложени шаблони за дизайн“. В тази серия ще разкрием всеки модел на проектиране от нулата.





Простото познаване на език за програмиране и неговите конструкции няма да ви направи по-добър програмист или разработчик. Изискват се знания за дизайнерски модели, за да се създаде софтуер, който да работи днес и в бъдеще.

Много разработчици вече са се сблъсквали с тези дизайнерски проблеми, с които се сблъсквате в момента или ще се сблъскате в бъдеще. Те са посочили стандартен начин за справяне с този проблем. Така че с помощта на дизайнерски модели получавате предимството от използването на доказани техники.



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

Повечето програмисти просто се опитват да разрешат проблема, с който се сблъскват, без да се притесняват относно дизайнерските модели, излишния код или дори тясното свързване. Но добрите програмисти започват по различен начин. Те мислят за днешните изисквания, бъдещите изисквания, поддържането на кода и повторното използване на кода.

Добрите програмисти не бързат да започнат да кодират, след като получат изискванията. Те седят и мислят за проблема дали техният дизайн ще работи. Ако да, дали ще работи след 6 месеца, когато изискванията ще се променят.



Добрите програмисти си вземат писалката и хартията и започват да проектират своите класове и връзката между класовете. Те се опитват да получат свободно свързване и висока сплотеност в дизайна си, като същевременно правят всичко това, като имат предвид обектно-ориентираните принципи. Те не влизат веднага в кода на ниско ниво. За да проектирате гъвкав и многократно използван софтуер, трябва да следвате този подход, в противен случай винаги ще откриете, че променяте кода, който сте написали по-рано.

Има само едно нещо, което е постоянно в софтуерната индустрия и това е Промяна. Изискванията със сигурност ще се променят. И така, как да проектираме софтуера, който вашият код може лесно да адаптира към бъдещите изисквания? За това трябва да започнете по-рано и да го проектирате по такъв начин, че бъдещите изисквания да не нарушават предишния ви код.

Как мога да направя това?

Е, това може да се направи, като се следват Принципите на проектиране и Моделите на проектиране, базирани на тези принципи.

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

Когато казвам най-важното, това отразява общия проблем, който се решава от Strategy Pattern.

Какво е стратегически модел?

Ето определението направо от книгата „Банда на четирима“: „Шаблонът на стратегията се използва за създаване на взаимозаменяемо семейство алгоритми, от които се избира необходимия процес по време на изпълнение”.

В случай, че стене е в състояние да разбере, не се притеснявайте, ще го обясним в aпо-простначинза теб даразберете.

Нека първо разберем проблема и след това ще видим как стратегическият модел може да го реши.

В горната UML диаграма имаме абстрактния клас Animal и два конкретни класа Dog и Bird, простиращи се от супер клас Animal.

Така че нека дефинираме абстрактния клас на животните и два конкретни класа, куче и птица.

Какво мислите за горния дизайн? В дизайна ни има една голяма грешка.

Всички животни не могат да летят, както в горния случай кучето не може да лети. Но все пак има поведение на „муха“.

Направихме грешка, като написахме абстрактния метод fly () в клас Animal. Този дизайн ще принуди всеки подклас Куче, Птица, Пингвин, Крокодил, Гъска и др. Да приложи метода fly ().

Трябваше да разберем, че летенето е способност, която не всички животни ще притежават. Предоставяйки метод fly () в абстрактния клас на животните, ние сме задали летателната способност във всички подкласове, което не е правилно за всички подкласове на животните.

Може би си мислите какъв е проблемът при внедряването на метода fly в подкласовете. Въпреки че можете да приложите метода fly () в нелетящите животински подкласове, за да отпечатате просто „Не мога да летя“. Но проблемът е, че все още държите мухата на нелетящи животни. Това не е вярно.

Какво е чувството да се обадиш на dog.fly () или крокодил.fly ().

И така, сега разбрахме, че нашият дизайн не е правилен и трябва да премахнем метода fly () от подкласа Animal.

Какъв е другият начин за проектиране на нашите класове по начин, по който нашият дизайн не налага всички подкласове на животните да имат поведение на мухи.

Едно решение, което веднага идва на ум, е, че можем да направим летящ интерфейс с метод на летене и само животни, които могат да летят, ще приложат този летящ интерфейс. По този начин няма да наложим всички подкласове на Animal да определят поведението на мухата. Така че нека кодираме този подход към дизайна.

Сега нашият клас Animal ще изглежда като кода по-долу след премахване на метода fly от клас Animal.

Сега нека дефинираме летящия интерфейс

Сега класът Dog ще бъде промененкатокода по-долу и не е необходимо да има поведение на летене.

Нека да видим някои от нашите подкласове за животни, които ще имат летящо поведение.

Решихме предишния си проблем, но се сблъскахме с нов проблем и това е „Дублиране на кода“.

Кажете, ще имаме 100 различни подкласа на летящи животни. Трябва да дублираме кода за поведение на мухата, тъй като летящият интерфейс не може да осигури никаква реализация за поведение на мухата, а по-късно, ако искаме да променим изпълнението на метода fly () във всеки подклас, ще трябва да отворим този клас и да променим кода което е лошо. Липсва ни нещо голямо и тоест не можем да променим летателното поведение на клас по време на изпълнение.

Но не се притеснявайте, стратегията Pattern е там, за да ви измъкне от този проблем.

Така че нека рефакторираме нашия код, за да използваме стратегически модел.

Летящият интерфейс ще остане същият, какъвто е. Сега, вместо всеки летящ подклас, реализиращ самия летящ интерфейс, ще определим отделни конкретни класове, които ще реализират различно летящо поведение. Нека да видим как да го направим.

И така, как всичко работи, нека видим TestClass

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

Кога да използвам стратегически модел?

Когато искате да можете динамично да променяте поведението по време на изпълнение.

За да сте сигурни, че разбирате ясно стратегическия модел, нека вземем друг пример.

В горния клас Служител ние определяме заплащането на служителя в зависимост от неговото / нейното назначение. Ако служителят е „стажант“, ние добавяме 10% бонус към основната заплата, за да изчислим действителното заплащане.

Ако даден служител е „Уеб разработчик“, ние добавяме 20% бонус към основната заплата, за да изчислим действителното заплащане и подобен процес следва за други видове служители. Въпреки че нашият алгоритъм за изчисляване на действителното заплащане е много лесен за улесняване на разбирането, но през повечето време той включва много сравнения и изчисления.

И така, какво не е наред с кода на класа на служителите?

Е, кодът за изчисляване на заплащането (getPay ()) е статичен. Да предположим, че искам да променя бонуса за „Стажант“ от 10% на 14%. Ще трябва да отворя кода на класа на служителя и да го променя.

И друг проблем е, че не мога да променя алгоритъма за заплащане на служител по време на изпълнение. И така, как да го направя? Шаблонът за стратегия се използва специално за справяне с този вид проблеми.

Нека рефакторираме кода, за да използваме стратегически модел.

Ще определя няколко алгоритма за изчисляване на заплащането. Тогава ще мога да използвам всеки от тези алгоритми за изчисляване на заплащането по време на изпълнение.

Сега да видим как ще се промени класът на служителя.

c ++ пример за пространство на имена

Забележка: Премахнах логиката за изчисляване на заплащането от клас Служител и създадох зададен метод PayAlgorithm (), чрез който ще задам PayAlgorithm, който искам да използвам за изчисляване на заплатите.

Това ще ми даде гъвкавост да изчислявам заплащането, като посочвам всеки PayAlgorithm динамично по време на изпълнение. Също така имайте предвид, че по-късно, ако трябва да променя логиката за изчисляване на заплащането, мога да създам нов PayAlgorithm и да го използвам за изчисляване на заплащането. Не е нужно да променя предишния код, нали е страхотно?

Нека видим как работи.

Надявам се, че много добре сте разбрали модела на стратегията. Най-добрият начин да научите нещо е чрез практикуване.

В случай, че имате някакви запитвания, свързани със стратегически модел или друг модел, оставете заявките си по-долу.

Внимавайте за следващата публикация, където ще разкрием един от най-популярните Design Pattern, Factory Pattern.

Дотогава можете да изтеглите играта с кода и да сте сигурни, че сте циментирали стратегическия модел в главата си.

Имате въпрос към нас? Споменете ги в раздела за коментари и ние ще се свържем с вас.

Подобни публикации: