You are on page 1of 36
¥ Numankacar / design-patterns-for-humans @vinne 1) ser 3 rom 32 Code [1 Rueequess dQ Actions ME Projects @ 5A Wiki Security © Li sights Design Patterns for Humans” An ultra-simplifed explanation 218 conn Borne 20 packag © Oretene 122 conttutor a a Cen ven te | Wot | ee | EES Thi branch ie 15 1 README md (Change iense to cetie commons rite behind kamranshresamastr MPullrequest 9 FREADME md DESIGN PATTERNS FOR HUMANS! Be uve ‘Atopic that can easly make anyone's mind wobble. Here I try to make them stick in to your mind (and maybe explaining them in the simplest way possible. plied explanation to design patems! jy Did you like this guide and want more of the similar content? Buy me a coffee and subscribe to Hugobots! § Introduction Design patterns are solutions to recuring problems: guidelines on how to tackle certain problems. They ae not classes, packages of libraries that you can plug into your application and wat for the magic te happen. These are, rather, guidelines on how to tackle certain problems in certain situations. Design patterns are solutions to recuring problems; guidelines on how to tackle certain problems Wikipedia describes them as ring, a software design pattern isa general reusable solution to commonly occurring prob ven context in software design, itis nota finished design that can be transformed directly into source or machine isa description or template for how to solve a problem that can be used in mary different situations Ay Be Careful © Design patterns are not asiver bullet to all your probleme 1+ Domnot try t force thems bad things are supposed to happen if done co. Keep in mind that dasign patterns are solutions to problems, not solutions finding problems; so don't overthink. + Fused in a correct place in a correct manner, they can prove to be 2 savior or elee they can result in a horrible mess of a code. ‘Aliso note thatthe code samples below are in PHP-7, however this shouldnt stop you because the concepts are same “anyways. lus the support for other languages ie underway Types of Design Patterns © Creational © Structural © Behavioral Creational Design Patterns In plain words CCreationa patterns are focused towards how to instantiate an object or group of related objects. Wikipedia says In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, tying to create objects ina manner suitable tothe situation. The basic form of abject creation could result in design problems or added complexity to the design, Creational decign patterns solve thi problem by somehow controlling thie abject cretion. © Simple Factory > Factory Method Abstract Factory © Bulder © Prototype » Singleton Q Simple Factory eal word example CContiser, you are building @ house and you need doors t would be a mass if everytime you need! a doar, you jut an your carpenter clothes and start making 2 door in your house. Instead you get it made from a factory. In plain words ‘Simple factory simply generates an instance for client without exposing any instantiation logic tothe client Wikipedia says In object-oriented programming (OOP), a factory is an object for creating other objects —formelly a factory isa function or ‘method that returns objects of a varying prototype oF cass from some method call which is assumed t0 be “new Programmatic Example Fist of all we have a door interface and the implementation public function getwidth()= Float: public function getHeight(): floats > class WoodenDoor implements Door £ protected $ulath; protected Sheights pubite function _corstruct(#ioat futeth, float ghetant) 4 ‘Sents-ondatn = Sadat Seba sheient = Soeights } public function getiidth(): float 4 return Sthis->ubath; » public fimction getHetght(): Float q return Sthis-ohedghts » ‘Then we have our door factory that makes the door and returns it chs torractery ‘ public static function nakeDoor($width, Sheight): Door ‘ return new KooderDoor(Swidth, Sheight); 2 ‘nd then It can be used as ‘$00r = DoorFactory::#akeDo0r(108, 200) echo “Width: " . Sdoor->getutetni echo “Weight: ". $doer-paetHeght()s When to Use? ‘When creating an object isnot usta few assignments and involves some logic it makes sense to put it in a dedicated factory Instead of repeating the same code everywhere. [& Factory Method Fea world example Consider the case of a hiring manager. Iti impossible far one person ta interview for each of the postions. Based on the job opening, she has to decide and delegate the interview steps to different people In plain words Itprovides a way to delegate the instantiation logic to child classes, wikipedia says In class-based programming, the factory method pattern is a creational pattem that uses factory methods to deal with the [problem of coating objects without having to specify the exact case of the object that wile created. This is dane by creating objecs by calling a factory method—elther specified in an interface and implemented by child classes, or Jmplemented in 2 base class and optionally overridden by derived classes—rather than by calling @ constructor. Programmatic Example Taking ourhiring manager example above. First of all we have an interviewer interface and some implementations for it public function askouestions(): ? lass Developer tnolesents Intervieuor public function askauestions() { echo “Asking about design patterns"; > » class Comunityexecutive inplenents interviewer t public function askauestions() 4 + [Now let us create our Hiringonager abstract clase Hiringtonager « 11 Factory wethod fanstract protected function maketnterviewer(): Interviewers buble function takenntervseu() { Sintonsseuer ~ fete onakalntereiover(); ‘incervdeuer-askovestions(): + » ‘Now ary child can extend it and provide the requited interviewer class Developnentianager extends Miringianager ‘ protected function askeinterviewer(): Interviewer { return neu Developer()s > » class arketinghanager extends Miringianager { protected function aokelnterviewer(); Interviewer 4 return ness Conmunttyexecuttve(); } > ‘and then it can be used as ‘Seetanager = nev Developnenthanager(s [Seeulanagerstekezsterveu()s // outa asking about design potters “narkatinganager ~ neu Horketinganager()s [Smarkatinghanager->taketntervien(); // output: Asking about community bullding. When to use? Useful when there some generic processing in class but the required sub-class is dynamically decided at cuntime, Or putting it in ther words, when the client doesnt know what exact sub-class it might need. A Abstract Factory eal world example “tending our door example from Simple Factory. Based on your needs you might get a wooden dacr fram a wooden daor shop ton door rom an iron shop or @ PVC door fom the relevant shop. Plus you might need a quy with dtferent kind of specialities to fit the door for examole a carmenter for wooden door. welder for iron door ate As vow can 228 there isa dependency between the doors now, woaden door needs carpenter, iron door needs a welder ete Inplain words ‘A factory of factories a factory that groups the individual but related/dependent factories together without specifying their concrete classes. wikipedia says ‘The abstract factory pattem provides a way to encapsulate a group of individual factories that have a common theme without specifying ther concrete classes Programmatic Example ‘Translating the door example above. First of all we have our Boor interface and some implementation fort nterface o00r ‘ public function getoescription(): ? class wooderboor inplenerts Door { public function getDescription() 4 sche °F an a wooden door’; } > class Irordoor snplenents Door « pubite function getoescraptton() 4 echo °F an an tren doors » » ‘Then we have some fiting experts for each door type ncerface ooorFsingtapert public function getDescription()s > class Welder ieplonents DoorFiteingsxpert t public function getoescription() { echo “T can only #1 iron doors"; > » class Carpenter inplenents DoorFittingexpert { public function getDescription() 4 echo °T can only #1 wooden doors"; } [Now we have our abstract factory that would let us make family of related objects ie. wooden door factory would crete a ‘wooden door and wioaden door fiting expert and iron door factory would create an iran daar and iron door fitting expert nterface ooorFactory ‘ public function makedoor(): Ssers public function makeFittingexpert()* OooeFittingexpents > 11 Weaden factory ta return carpenter and wooden door ‘lass WoodenDoorFactory inplenents DoorFactory « pmite function makeooor(): 200" 4 return neu KooderDo0r()$ » public function makeFittingtpert()! Dooorittlngexpert 1 return neu Carpantar()s ? » 11 Aron doce Factory to get inom door and the relevant Fitting expert Class IrordoorFactory implenents DoorFactory public function maketoor(): 200" 4 return neu trerdoor()s » public function makeFiceingexpert(): OoocFittingexpert 4 return new Kelden()3 > ‘And then it can be used as ‘ucodenractory = neu wooéenvoerractory(): ‘Secor = SwcodenFactory-akeD00r(); ‘Sexpert = Swoocenractory-akericcingexper( ‘Sdoor-rgetbeseription(); // output: T an a wooden door Sexpert-vgetbescrigtion(); // Output: 1 can only f1t wooden doors 11 Sane for t00n Factory ‘StroaFactory = neu TronDeorFactory ‘sdeor = Sironractory-nakeveor() ‘expert ~ Seantactory-onaker ited ngexpert(); ‘Sdoor-dgeroescription(); // output: 1 an an iron door ‘Fexpert-ogetDescristion();,// output: 1 can only fit tren doors ‘As you can see the wooden door factory has encapsulated the anganter and the wooden geor also iron door factory has encapsulated the iron door and welder. And thus ithad helped us make sure that foreach ofthe created door, we do not get ‘avwrong fiting expert When to use? ‘When there are interrelated dependencies with net-that-simple creation logic involved & Builder Real world example Imagine you are at Hardee's and you order a specific deal, lets say, "Big Hardee" and they hand it over to you without any questions; this isthe example of simple factory. But there are cases when the creation logic might involve more stops. For ‘example you want a customized Subway deal, you have several options in how your burger is made e-9 what bread do you ‘want? what types of sauces would you like? What cheese would you want? ee. In such cases builder pattern comes to the Inplain words Allows you to create different flavors ofan object while avoiding constructor pellation, Useful when there could be several flavors ofan object. Or when there are alot of steps involved in creation of an object. Wikipedia says ‘The builder patter isan object creation software design patter with the intentions of finding a solution tothe telescoping constructor ant-pattern ‘Having said that let me add a bit about what telescoping constructor ant-pattern is. At ane point or the other we have all seen a constructor lke below public function _construct(Esize, Scheese = true, Speppereni = true, Stonato - false, $lettuce ~ true) « y As you can see: the number of constructor parameters can quickly get out of hand and it might become dificult to understand the arrangement of parameters, Plus this parameter list could keep on growing ifyou would want to add more options in future ‘This is called telescoping constructor ant-pattern. Programmatic Example ‘The sane alternative isto use the builder pattern, Fist ofall we have our burger that we want to make class burger ‘ protected $size; protected Scheese = falas; protected Spepperont = false: protected Slettuce ~ false: public function _corsteuct(BurgerBut idan Shuler) 1 ‘this >size = sbutlder->size: Sehsrcheese ~ Soutlder-rcheese; Sthis-»pepperont ~ Sbuilder->pepperoni ‘this lettuce = shuilder-slettuce; Sehs stomata ~ Soutlder->tonato; } ‘And then we have the builder class BurgerBuiléer £ public $siz0; public Scheese = false: public Spepperont = false; public Slettuce = false; public stonato = false; public function _construct(int $size) 4 Seta aize = §eizes + public function addPepperani() 4 Sthis-»pepperent = tru return Sthis: > public function addLettuce() 4 Sehis lettuce - trues return Sthis: > public function adécheese() 4 senis-senaese = rues return $this: public function adérensto() { Sthis rtonato = trues return $this: ? public function but2e(): Burger { return new Surger(Sthis)s > » ‘And then it can be used as: “sburger = (oa Surgeroutider(18)) >edePepperont() >adetettuce() aseronato() sbulla()s When to use? ‘hen there could be several favors of an object and to avoid the constructor telescoping The key lfference from the factory pattern is that: factory pattem is tobe used when the creation is @ one step process while bulier pattem isto be used when the creation isa mult step process € Prototype Real world example Remember dolly? The sheep that was cloned! Lets not get into the details but the key point here i that is all about cloning In plain words create object based on an existing object through cloning. Wikipedia says ‘The prototype pattem isa creational design pattem in software development. itis used when the ype of objects to creat is determined by a prototypical instance, which is cloned to produce new objects. In short it allows you to create a copy of an existing abject and modifi to your nee, instead of going through the trouble of ‘creating an object from scratch and setting it up. Programmatic Example {In PHP, it can be easily done using clone class sheep £ protected $nane; protected Scategory: public function _construct(string fname, string category = ‘Mountain sheep") q ‘sthis-dnane = Sane; Sens: category ~ Scategory; + public function setene(string Soame) 4 ‘Sthis-onane ~ Sane; : public function getmane() 1 return this-onane; ? public function setcategory(string Scategory) { Sthis-rcategory = Scategorys > public function getcategory() 4 return this >eategony; + » ‘Then it can be cloned lke below original ~ nex Sheop( Jolly"): echo Soriginal->getiane(); // Jolly echo Foriginal-rgetcategory(); // Mountain sheep 11 Clove and wodify what 1s required {feloned = clone foriginal; |Felonee->settine( 00119"); echo Seloned-rgetiane(): // Dolly ocho eloned->gatcategory(); // Nountain shosp {Also you could use the magic method __lone to modify the cloning behavior. When to use? When an objet is required thats similar to existing objector when the creation would be expensive as compared to daring. 6 Singleton Real world example ‘There can only be one president of @ country at a time, The same president has to be brought to action, whenever duty calls President here is singleton. Inplain words Ensures that only one abject of particular clas is ever created. Wikipedia says In software engineering the singleton pattern i a software design pattern that restricts the instantiation of a class to one: ‘object. This is useful when exactly one object is needed to coordinate actions across the system. Singleton pattern is actually considered an anti-patten and overuse oft should be avoided. It is not necessarily bad and could hhave some valid se-cases but should be used with caution because it introduces a glabal state in your application and change to itin one place could affect in the other areas and it could become prety dificult te debug, The other bad thing about them ist ‘makes your code tight coupled plus mocking the singleton could be dificult Programmatic Example To create a singleton, make the constructor private, cisable cloning, disable extension and create static variable to house the tance ‘final class Prestcent { private static Sinstances private function _construct() 4 17 Wide the constructor ? public static function getinstance(): President 4 F (Iself:sinseance) ¢ Self: :Sinstance = neu sel#(): » return self: :$lnstance; } private function _clone() 4 17 visable cloning » private function _wekeup() 4 11 visable unserialize ? ‘Then in order to.use ‘Spresicenci = President: getunstance(): ‘Sprecigent2 ~ President: sgattnetance()3 var_dump(Spresidenta === Sprestdent2); // true Structural Design Patterns In plain words Structural patterns are most concerned with object composition or in other words how the entities can use each other. Or yet another explanation would be, they help in answering “How to build a software component?” Wikipedia says In software engineering, structural design patterns are design patterns that ease the design by identifying a simple way to ‘realize relationships between entities, Adapter © ridge > Compasite + Decorator © Facade © Flyweight, * Prog & Adapter Fea world example Consider that you have some pictures in your memory card and you need to transfer them to your computer. In order to transfer them you need some kind of adapter that is compatible with your computer ports so that you can attach memory card to your computer. In this case card reader isan adapter. Another example would be the famous power adapter a three legged plug can't be connected toa two pronged outlet, it needs to use a power adapter that makes it compatible withthe ‘wo pronged outlet, Yet another example would be a translator translating words spoken by one person to another In plain words ‘Adapter pattern lets you wrap an otherwise incompatible object in an adapter to make it compatible with another class. wikipedia says In software engineering, the adapter pattern isa software design pattern that allows the interface ofan eaisting cass to be used as another interface. tis often used to make existing classes work with others without modifying their source cade, Programmatic Example Consider a game where there isa hunter and he hunts ons. Fist we have an interface Lion that all types of lions have to implement Anterface Lion ‘ public function rear()s » class Africantion iuplenerts Lion { pubic function roar() 4 } > class AstonLion snplesents Lion public function rosr() 4 + ? ‘And hunter expects any implementation of Lion interface to hunt. class Hunter « inate function hune(Lion $1100) q > ? Now let's say we have toad a Wiiledog in our game 11 baogter around wid dog to ake it compatible with oun Class wildoogadapcer inplenents Lion t protected $does publte function _construct(ulddog $éog) 1 ‘Sthis-odog = $8; ? public function resr() { Sthisrdog-rbarkQ)s > » ‘And now the Utldpog can be used in our game using wtlébogtéapter ‘sultdoog = new W2le0080) [ulldDogsdzpter = now il Ldbogecapten(Gut1eDog); ‘shunter = naw HunteQs ‘Shunter->hunt SutldDogAdenter); Bridge & Bridg eal world example Consider you have a website with different pages and you are supposed to allow the user to change the theme, What would you do? Create multiple copies of each ofthe pages foreach ofthe themes or would you just create separate theme anct load them based on the user's preferences? Bridge patter allows you to do the second ie. Without Bridge “AN IN a /t\. Projects (Theme) ‘About (Theme) (Theme) wl. In Plain Words bridge pattern is about preferring composition another object with a separate hierarchy. inheritance. implementation details are pushed from a hierarchy to Wikipedia says ‘The bridge pattern isa design patter used in software engineering that is meant to “decouple an abstraction from is implementation zo thatthe two can vary independently” Programmatic Example ‘Translating our WebPage example from above, Here we have the WebPage hierarchy snvarface webpage ‘ public function _construct(Thene $theme); public function getcontent(); » lass About dnplenants neePage t protected sthenes public function _corstruct(Thene Sthene) i Ses theme = gehen } public function getcontent() q return “About page in” . sthts->thene-getcolor(); ? > £ protected sthane: Dubie function _construct(Thene Shana { Sthis rthane - sthene: > public function getcontent() 4 retuna "Corcors page tn". gthls-rthene-gatcolon(); } > ‘nd the separate theme hierarchy nzacface Thane { public function getColor()s > class DarkThone inplenents There public function getcalor() q return “Dare Black's ? » Class LightThene luplenents Theme ‘ public function getcetor() { return “OFF white’: > » Class Aquathene inplenents There public function getcalor() q ? return “Light blue"; ‘And both the hierarchies ‘SdankThone ~ nou Oarketne(); ‘bout = naw abour(Sdarkthene): ‘Feareers ~ naw Corssrs($darkThene); echo Sabout-ogetcontere(); // “about page in Dark slack’ cho careers: >getcontent(); // "Careers sage in Dank Slack"; @ Composite Rea worl example Every organization i composed of employees. ach ofthe employees has the same features ie. has a salary, has some responsibilities, may or may not report to Someone, may oF may not have some subordinates etc Inplain words Composite pattern lets clients treat the individual objects in a uniform manner. wikipedia says In software engineering, the compesite pattern sa partitioning design pattem. the composite pattern describes that a ‘group of objects isto be tested inthe same way asa single instance of an object. The intent of 8 composite is to “compose” objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients ‘reat individual objects and compositions uniformly Programmatic Example Taking our employees exemple from above, Here we have different employee types interface Employee € public function _consteuct(string fname, float $salary); public function getNane():_ strings public function setsalary(fleat $salay): pubite function getsalary(): float; public function gettoles(): arrays > class Voveloper inplenents Employee t protected §ealacys protected Snane; protected Sroles: public function _construct(string $name, flost Ssalary) { Sthis mane = Sane; Senie-osalary ~ Sealer » public function getnane(): string { return Sthis-prane; > public function setsalary(float ssalary) { Sthie nealary ~ Sealarys > public function getSalary(): float i return Sthis->salarys } public finction getRoles(): array q return sthis-oroles: » » class Designee taplenents Employee £ protected ssalacy protected Srane; protected sroless public function _construct(string fama, float fzalary) 4 Sch ynane = Snane: Sthis rsalary = Ssalarys > public function getNane(): string 4 return this rane; } public function setSalary(float fsalary) 4 sente-oeslary ~ sealer public function getsalary(t 1 Float retuen Sthis->salarys ? public function gettoles(): array { retum Sthis-rroles; > ‘Then we have an organization which consists of several diferent types of employees Class organization t protected Senployees; public function addemployee(Esployee Senployee) 4 ‘sthis penployees() » enployees public function getetsalaries(): flost { & SretSalary ‘oreach (Sinis-renployees a5 Semployee) { Snetsalary += Senployee->getSalary(); > retuen fetsalarys ‘And then it can be used as 11 Prepare the enployees [Fiona = new Devezoper(' Joba Doe", 12900); ‘Hane = ne Dersgnen(" ane 006", 15008)5 11 bad thom to onganizstion “organtzation ~ nay nganizetion() ‘Sorgantzation-radcteployee( john): Serganization-radsEeployee(Siane); ocho “et salaries: * . fongantzatton->gethetsalaries(); // Net Salaries: 27000 & Decorator eal world example Imagine you run a car service shop offering multiple services. Now haw do you calculate the bill tobe charged? You pick ‘one service and dynamically keep adding toi the prices for the provided services tl you get the final cost. Here each ype of service i a dacorator In plain words ‘Decorator patesn lets you dynamically change the bhavior of an abject at run time by wrapping them in an olajct of a decorator class. Wikipedia says In object-criented programming, the decorator pattern is @ design pattern that allows behavior to be added to an individual ‘object either statically or dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is often useful fr adhering tothe Single Responsibility Principle, ait allows functionality to be dived between lasses with unique areas of concer. Programmatic Example Lets take coffee for example. First ofall we have a simple coffee implementing the cote interface interface coffer « public function getCont(); public funetion getoescription(): ? class Simplecortee inplenents coffee t public function getCost() i } public function getdescription() 4 return “simle coffee’: ? \We vant t2 make the cose extensible to allow options to masity it required, Lets make some add-ons (decorators) class mikcoffee luplenents Coffee 1 protected Scoffee: public function _construct(Coffee Scoffee) 4 Ses scoffee = scotfecs } pumate function getcost() q return Sthis->coffee-ogetcost() + 2: } public function getdescription() 1 return Sthis-ocoffee-sgetpescription() . ‘ilk’: ? > class whtpcoffee luplenents Coffee 1 protected Scoffee: public function construct Coffee Scoffee) 4 Sens. scoftee ~ scoftees + public function getCont() 4 return Sthis->coffee->getcest() + 5: : public function getdescription() 1 return Sthis-scoffee-ogetpescription() . ‘whip! ? > class vantIlacof fee implements Coffae 1 protected Scoffee: public function _construct(Coffee Scoffee) 4 sens scottee = scottecs + public function getCoct() 4 return Sthis-veoFfaa-ogetcost() + » public function getdescription() 4 return $this->coffee-ogetpescription() . ‘ vanilla" » Lets make a coffee now ‘SsomeCoffee = naw Stoplecoftee(): echo SsoneCoffee-reatCost(); // 10 echo Ssonecoffee-sgetbescrigtion i 11 staple coffen ‘SsoneCoffee = naw MiIkCoFfee(SsaneCoFFee) echo Ssonetoffee-getcost(); // 12 cho FsomcCoffee.ygetDescription(); // Sisple Coffee, ail ‘Ssonacoffes — neu shipcoFfee(Seonacoffee)s ocho soneCoffee >getCost(); // 17 ocho FsoneCoffee-rgetDescription(); // Sinple Coffee, milk, whip ‘$eomecoffes ~ nou Vantitecortes(Ssomacoffee); echo $sonecorfee-ngetcost()s // 20 echo Ssonecoffee-rgetDescrlgtion / Staple Coffee, milk, whip, vanilla Facade eal world example Howe do you tun on the computer? “Ht the power button” you say! Thats what you believe because you are using asimple Jnverlace that computer provides onthe out, internally has to do lat of stu to make it happen Tis simple interface to the complex subsystem isa facade tn plain words Facade pattern provides a simplified interface to a complex subsystem. Wikipedia says ‘A facade is an object that provides a simplifed interface toa larger body of code, such asa cas bar Programmatic Example ‘Taking our computer example fiom above. Here we have the computer class class computer t public function getElectrieshock() i echo “aueh!"; } public function wkesoundt) q echo “Beep beep!" » public function shewtossingscreen() 4 echo “Loading. > public function ban() { ocho “Ready to be ured!" +

You might also like