ebook img

The Clean Architecture in PHP PDF

251 Pages·2015·2.26 MB·English
Save to my drive
Quick download
Download
Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.

Preview The Clean Architecture in PHP

The Clean Architecture in PHP Kristopher Wilson Thisbookisforsaleathttp://leanpub.com/cleanphp Thisversionwaspublishedon2015-04-24 ThisisaLeanpubbook.LeanpubempowersauthorsandpublisherswiththeLeanPublishing process.LeanPublishingistheactofpublishinganin-progressebookusinglightweighttools andmanyiterationstogetreaderfeedback,pivotuntilyouhavetherightbookandbuild tractiononceyoudo. ©2013-2015KristopherWilson Dedication Firstandforemost,Idedicatethisbooktomywife,Ashley.Thankyouforallowingmetospend somuchtimestaringatmillionsofdotsonascreen. Secondly, to my parents, who worked so hard to make sure their children had everything they needed and wanted, and for encouraging me to follow my dreams, however odd they may have been. Contents Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i Organization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i TheAuthor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i AWordaboutCodingStyle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ii The Problem With Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 WritingGoodCodeisHard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 WritingBadCodeisEasy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 WeCan’tTestAnything . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 ChangeBreaksEverything . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 WeLiveorDiebytheFramework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 WeWanttoUseAlltheLibraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 WritingGoodCode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 WhatisArchitecture? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 WhatdoesArchitectureLookLike? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 LayersofSoftware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 ExamplesofPoorArchitecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 CostsofPoorArchitecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Coupling,TheEnemy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 SpaghettiCoupling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 OOPCoupling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 WhyisCouplingtheEnemy? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 HowdoweReduceCoupling? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Your Decoupling Toolbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 DesignPatterns,APrimer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 TheFactoryPatterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 RepositoryPattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 AdapterPattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 StrategyPattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 LearningMoreDesignPatterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 SOLIDDesignPrinciples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 CONTENTS SingleResponsibilityPrinciple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 Open/ClosedPrinciple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 LiskovSubstitutionPrinciple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 InterfaceSegregationPrinciple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 DependencyInversionPrinciple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 ApplyingSOLIDPrinciples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 DependencyInjection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 InversionofControl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 WhentouseDependencyInjection . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 HandlingManyDependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 Arewestillcoupling? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 DefiningaContractwithInterfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 InterfacesinPHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 UsingInterfacesasTypeHints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 UsingInterfacesasaContract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 MakingThirdPartyCodeConformtoContracts . . . . . . . . . . . . . . . . . . . . . 56 AbstractingwithAdapters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 SettinguptheAdapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 Howdoesthishelp? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 The Clean Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 MVC,anditsLimitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 MVCinaDiagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 TheMVCComponents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 MVCIsn’tGoodEnough . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 ObeseModels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 MoreLayersforAlloftheThings! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 TheCleanArchitecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 TheCleanArchitecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 TheOnionArchitecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 FrameworkIndependence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 TheProblemwithFrameworks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 FrameworkIndependence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 ThisisaLotofWork . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 DatabaseIndependence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 DomainModels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 DomainServices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 DatabaseInfrastructure/Persistence. . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 OrganizingtheCode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 CONTENTS WrappingitUp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 ExternalAgencyIndependence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 UsingInterfaces,AdaptersandDependencyInjection . . . . . . . . . . . . . . . . . . 94 Benefits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 A Case Study in Clean Architecture . . . . . . . . . . . . . . . . . . . . . . . . 97 TheBillingSystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 ApplicationWorkflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 BuildingOurDomain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 SettinguptheProject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 CreatingtheEntities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 DomainServices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 WrappingitUp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 ZendFramework2Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 InstallingwithComposer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 CleaninguptheSkeleton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 SettingupOurDatabase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 TableGatewayFactory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 WrappingitUp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 OurApplicationinZendFramework2 . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 CustomerManagement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 OrderManagement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 InvoiceManagement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 Doctrine2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 RebuildingthePersistenceLayer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 CreatingDoctrine-basedRepositories . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 EntityMapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 IntegratingZendFrameworkandDoctrine . . . . . . . . . . . . . . . . . . . . . . . . 203 InjectingtheNewRepositories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 UpdatingtheHydrators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 SwitchingtoLaravel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 SettingupLaravel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 ConfiguringDoctrine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 SettinguptheDashboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 CustomerManagement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 OrderManagement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 InvoiceManagement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 NextSteps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 CONTENTS Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 Introduction Figuring out how to architect a brand new application is a big deal. Doing it the wrong way can lead to a huge headache later. Testing can become hard – or maybe even impossible – and refactoringisanabsolutenightmare. While the methods outlined in this book aren’t the only way to go about developing an application,theydoprovideaframeworkfordevelopingapplicationsthatare: 1. Testable 2. Refactorable 3. Easytoworkwith 4. Easytomaintain Thisbookisforanyonewantingtobuildamediumtolargesizedapplicationthatmustbearound foralongtimeand/orbeeasilyenhancedinthefuture.Themethodsoutlinedinthisbookaren’t meantforallapplications,andtheymightbedownrightoverkillforsome. If your application is small, or an unproven, new product, it might be best to just get it out the door as fast as possible. If it grows, or becomes successful, later applying these principles may beagoodideatocreateasolid,longlastingproduct. Theprinciplesoutlinedinthisbookinvolvealearningcurve.Writingcodethiswaywillslowa developerdownuntilthemethodsbecomefamiliartothem. Organization This book begins by discussing common problems with PHP code and why having good, solid, clean code is important to the success and longevity of an application. From there, we move on todiscussingsomeprinciplesanddesignpatternsthatallowustosolveproblemswithpoorcode. Using these concepts, we’ll then discuss the Clean Architecture and how it further helps solve problemswithbadcode. Finally, in the second half of the book, we dive into some real code and build an application following this architecture. When we’re done with our case study application, we’ll start swappingoutcomponents,libraries,andframeworkswithnewonestoproveouttheprinciples ofthearchitecture. The Author My name is Kristopher Wilson. I’ve been developing in PHP since around 2000. That sounds impressive on the surface, but most of those years involved writing truly terrible code. I would Introduction ii havebenefitedgreatlyfromabooklikethisthatoutlinestheprinciplesofhowtocleanlyorganize code. I’ve done it all, from simple websites to e-commerce systems and bulletin boards. Mostly, I’ve concentratedonworkingonERP(EnterpriseResourcePlanning)systemsandOSS(Operational Support Systems) – software that runs the entire back office of large organizations, from manufacturing to telecommunications. I even wrote my own framework once. It was terrible, butthat’sanotherstory. I live in Grand Rapids, Michigan with my wife and our four cats (our application to become a registered zoo is still pending). I’m one of the founders of the Grand Rapids PHP Developers (GrPhpDev) group and am highly involved with organizing, teaching, and learning from the localcommunity. A Word about Coding Style I strongly prefer and suggest the use of PSR-2 coding standards¹. As a community, it makes it much easier to evaluate and contribute to one another’s code bases if the dialect is the same. I alsostronglysuggesttheuseofDocBlocksandhelpfulcommentsonclassesandmethods. However,forbrevity,thecodeexamplesinthisbookmakeafewdeviationsfromPSR-2standards, namely involving bracket placement, and don’t include many DocBlocks. If this is too jarring forthePSR-2andDocBlockfan,likemyself,Ihumblyapologize. ¹https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md The Problem With Code Writingcodeiseasy.Soeasythatthereareliterallyhundredsofbooks²claimingtheycanteach you to do it in two weeks, ten days, or even twenty-four hours. That makes it sound really easy! Theinternet islitteredwith articleson howto doit. Itseemslikeeveryoneis doingit and bloggingaboutit. Here’s a fun question: would you trust a surgeon or even dentist who learned their profession fromacoupleofbooksthattaughtthemhowtooperateintwoweeks?Admittedly,writingcode is nothing like opening up and fixing the human body, but as developers, we do deal with a lot of abstract concepts. Things that only exist as a collection of 1s and 0s. So much so that I’d definitelywantanexperienced,knowledgeabledeveloperworkingonmyproject. The problem with code is that good code, code that serves it’s purpose, has little or no defects, can survive and perform it’s purpose for a long time, and is easy to change, is quite difficult to accomplish. ²http://norvig.com/21-days.html

Description:
Leanpub empowers authors and publishers with the Lean Publishing .. to discussing some principles and design patterns that allow us to solve .. We're using controllers and views, so we've separated the presentation especially if we switch to using Eloquent ORM, which ships with Laravel.
See more

The list of books you might like

Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.