{"id":1070,"date":"2013-03-12T19:37:50","date_gmt":"2013-03-12T19:37:50","guid":{"rendered":"http:\/\/invisiblezero.net\/?p=518"},"modified":"2013-03-12T19:37:50","modified_gmt":"2013-03-12T19:37:50","slug":"the-whens-and-whys-for-design-patterns","status":"publish","type":"post","link":"http:\/\/ndthanh.com\/the-whens-and-whys-for-design-patterns\/","title":{"rendered":"The Whens and Whys for Design Patterns"},"content":{"rendered":"
<\/p>\n
Again, we have another article about Design Patterns<\/strong>. but this time it’s not the same :). There are plenty of articles that explain what design patterns are, and how to implement them; the web doesn\u2019t need yet another one of those articles! Instead, in this article, we will more discuss the when and why, rather than the which and how.<\/p>\n This article covers some of the various Agile Design Patterns, documented in Robert C. Martin\u2019s books. These patterns are modern adaptations of the original design patterns defined and documented by The Gang of Four in 1994. Martin\u2019s patterns present a much more recent take on the GoF\u2019s patterns, and they work better with modern programming techniques and problems. In fact, about 15% of the original patterns were replaced with newer patterns, and the remaining patterns were slightly modernized.<\/p>\n <\/p>\n Let\u2019s Start by Creating Some Objects<\/strong><\/span> When<\/span>: Use a Factory Pattern when you find yourself writing code to gather information necessary to create objects.<\/em><\/p>\n Why<\/span>: Factories help to contain the logic of object creation in a single place. They can also break dependencies to facilitate loose coupling and dependency injection to allow for better testing.<\/em><\/p>\n Finding the Data We Need<\/strong><\/span> The Gateway Pattern<\/strong> When<\/span>: When you need to retrieve or persist information.<\/em><\/p>\n Why<\/span>: It offers a simple public interface for complicated persistence operations. It also encapsulates persistence knowledge and decouples business logic from persistence logic.<\/em><\/p>\n In fact, the gateway pattern is just a particular implementation of another design pattern that we\u2019ll discuss shortly: the adapter pattern.<\/p>\n Go with the Proxy<\/strong> When<\/span>: You have to retrieve information from a persistence layer or external source, but don\u2019t want your business logic to know this.<\/em><\/p>\n Why<\/span>: To offer a non-intrusive approach to creating objects behind the scenes. It also opens the possibility to retrieve these object on the fly, lazily, and from different sources.<\/em><\/p>\n A proxy effectively implements the same interface as a real object and mimics its functionality. The business logic simply uses it as if it were a real object, but in fact, the proxy creates the object if one doesn\u2019t exist.<\/p>\n The active object pattern also played a part in early multi-tasking systems.<\/p>\n Okay, okay. That great and all, but how can we find the objects that we need to create?<\/p>\n Ask a Repository<\/strong> The repository pattern is different from the other patterns; it exists as part of Domain Driven Design (DDD), and is not included as part of Robert C. Martin\u2019s book.<\/p>\n When<\/span>: You need to create multiple objects based on search criteria, or when you need to save multiple objects to the persistence layer.<\/em><\/p>\n Why<\/span>: To let clients that need specific objects to work with a common and well isolated query and persistence language. It removes even more creation-related code from the business logic.<\/em><\/p>\n But what if the repository cannot find the objects? One option would be to return a NULL value, but doing so has two side effects:<\/p>\n A better approach is to return a null object.<\/p>\n The Null Object Pattern<\/strong> When<\/span>: You frequently check for null or you have refused bequests.<\/em><\/p>\n Why<\/span>: It can add clarity to your code and forces you to think more about the behavior of your objects.<\/em><\/p>\n It\u2019s not unusual to call many methods on an object before it can do its job. There are situations when you must prepare an object after its creation before you can truly use it. This leads to code duplication when creating those objects in different places.<\/p>\n You Need the Command Pattern<\/strong><\/p>\n When<\/span>: When you have to perform many operations to prepare objects for use.<\/em><\/p>\n Why<\/span>: To move complexity from the consuming code to the creating code.<\/em><\/p>\n This sounds good, doesn\u2019t it? In fact, it is quite useful in many situations. The command pattern is widely used for implementing transactions. If you add a simple undo() method to a command object, it can track all the undo transactions it performed and reverse them if necessary.<\/p>\n So now you have ten (or more) command objects, and you want them running concurrently. You can gather them into an active object.<\/p>\n The Active Object<\/strong> When<\/span>: Several similar objects have to execute with a single command.<\/em><\/p>\n Why<\/span>: It forces clients to perform a single task and affect multiple objects.<\/em><\/p>\n An active object removes each command from its list after the command\u2019s execution; meaning, you can execute the command only once. Some real world examples of an active object are:<\/p>\n Design patterns are here to solve problems.<\/p>\n The active object pattern also played a part in early multi-tasking systems. Each object inside an active object would keep a reference to the active object. They would execute a portion of their jobs and then put themselves back into the queue. Even in today\u2019s systems, you can use an active object to let other objects work while you wait for a response from another application.<\/p>\n Reusability<\/strong><\/span> Make Some Template Methods Instead<\/strong> When<\/span>: Eliminate duplication in a simple way.<\/em><\/p>\n Why<\/span>: There is duplication and flexibility is not a problem.<\/em><\/p>\n But flexibility is nice. What if I really need it?<\/p>\n It\u2019s Time For a Strategy<\/strong><\/p>\n When<\/span>: Flexibility and reusability is more important than simplicity.<\/em><\/p>\n Why<\/span>: Use it to implement big, interchangeable chunks of complicated logic, while keeping a common algorithm signature.<\/em><\/p>\n For example, you can create a generic Calculator and then use different ComputationStrategy objects to perform the calculations. This is a moderately used pattern, and it is most powerful when you have to define many conditional behaviors.<\/p>\n Discover-ability<\/strong><\/span> Present a Facade<\/strong> When<\/span>: To simplify your API or intentionally conceal inner business logic.<\/em><\/p>\n Why<\/span>: You can control the API and the real implementations and logic independently.<\/em><\/p>\n Control is good, and many times you need to perform a task when something changes. Users have to be notified, red LEDs have to blink, an alarm has to sound\u2026 you get the idea.<\/p>\n The popular Laravel framework makes excellent use of the Facade Pattern.<\/p>\n Subscribe to an Observer<\/strong> The observer pattern offers an easy way to monitor objects and take actions when conditions change. There are two types of observer implementations:<\/p>\n When<\/span>: To provide a notification system inside your business logic or to the outside world.<\/em><\/p>\n Why<\/span>: The pattern offers a way to communicate events to any number of different objects.<\/em><\/p>\n Use cases for this pattern are email notifications, logging daemons, or messaging systems. Of course, in real life, there are countless other ways to use it.<\/p>\n Coordinate The Effects<\/strong> When<\/span>: The affected objects can not know about the observed objects.<\/em><\/p>\n Why<\/span>: To offer a hidden mechanism of affecting other objects in the system when one object changes.<\/em><\/p>\n Singularity<\/strong><\/span> Use a Singleton<\/strong> When<\/span>: You need to achieve singularity and want a cross platform, lazily evaluated solution which also offers the possibility of creation through derivation.<\/em><\/p>\n Why<\/span>: To offer a single point of access when needed.<\/em><\/p>\n Or Write a Monostate Object<\/strong> When<\/span>: Transparency, derivabitility, and polymorphism are preferred together with singularity.<\/em><\/p>\n Why<\/span>: To hide from the users\/clients the fact that the object offers singularity.<\/em><\/p>\n Pay special attention to singularity. It pollutes the global namespace and, in most cases, can be replaced with something better suited for that particular situation.<\/p>\n Controlling Different Objects<\/strong><\/span> So you have a switch and a light. The switch can turn the light on and off, but, now, you\u2019ve purchased a fan and want to use your old switch with it. That\u2019s easy to accomplish in the physical world; take the switch, connect the wires, and viola.<\/p>\n Unfortunately, it\u2019s not so easy in the programming world. You have a Switch class and a Light class. If your Switch uses the Light, how could it use the Fan?<\/p>\n Easy! Copy and paste the Switch, and change it to use the Fan. But that\u2019s code duplication; it\u2019s the equivalent of buying another switch for the fan. You could extend Switch to FanSwitch, and use that object instead. But what if you want to use a Button or RemoteControl, instead of a Switch?<\/p>\n The Abstract Server Pattern<\/strong> When<\/span>: You need to connect objects and maintain flexibility.<\/em><\/p>\n Why<\/span>: Because it is the simplest way to achieve flexibility, while respecting both the dependency inversion principle and the open close principle.<\/em><\/p>\n PHP is dynamically typed. This means that you can omit interfaces and use different objects in the same context \u2013 risking a refused bequest. However, PHP also allows for the definition of interfaces, and I recommend you use this great functionality to provide clarity to the intent of your source code.<\/p>\n But you already have a bunch of classes you want to talk to? Yes, of course. There are many libraries, third-party APIs, and other modules that one has to talk to, but this does not mean that our business logic has to know the details of such things.<\/p>\n Plug in an Adapter<\/strong> When<\/span>: You need to create a connection with a pre-existing and potentially changing module, library, or API.<\/em><\/p>\n Why<\/span>: To allow your business logic to rely only on the public methods the adapter offers, and permit changing the other side of the adapter easily.<\/em><\/p>\n If either of the above patterns don\u2019t fit with your situation, then you could use\u2026<\/p>\n The Bridge Pattern<\/strong> When<\/span>: The adapter pattern is not enough, and you change classes on both sides of the pipe.<\/em><\/p>\n Why<\/span>: To offer increased flexibility at the cost of significant complexity.<\/em><\/p>\n The Composite Pattern<\/strong><\/span> Yes, yes we did. But this one is a bit different. It\u2019s the composite pattern, and like the active object pattern, it keeps a list of objects. But calling a method on a composite object calls the same method on all of its objects without removing them from the list. The clients calling a method are thinking they are talking to a single object of that particular type, but in fact, their actions are applied to many, many objects of the same type.<\/p>\n When<\/span>: You have to apply an action to several similar objects.<\/em><\/p>\n Why<\/span>: To reduce duplication and simplify how similar objects are called.<\/em><\/p>\n Here\u2019s an example: you have an application that is capable of creating and placing Orders. Assume you have three orders: $order1, $order2 and $order3. You could call place() on each of them, or you could contain those orders in a $compositeOrder object, and call its place() method. This, in turn, calls the place() method on all the contained Order objects.<\/p>\n The State Pattern<\/strong><\/span> A finite state machine (FSM) is a model that has a finite number of discreet states. Implementing a FSM can be difficult, and the easiest way to do so involves the trusty switch statement. Each case statement represents a current state in the machine, and it knows how to activate the next state.<\/p>\n But we all know that switch…case statements are less desirable because they produce an unwanted high fan-out on our objects. So forget the switch…case statement, and instead consider the state pattern. The state pattern is composed of several objects: an object to coordinate things, an interface representing an abstract state, and then several implementations \u2013 one for each state. Each state knows which state comes after it, and the state can notify the coordinating object to set its new state to the next in line.<\/p>\n When<\/span>: FSM-like logic is required to be implemented.<\/em><\/p>\n Why<\/span>: To eliminate the problems of a switch…case statement, and to better encapsulate the meaning of each individual state.<\/em><\/p>\n A food dispenser could have a main class that has a reference to a state class. Possible state classes might be something like: WaitingForCoin, InsertedCoin, SelectedProduct, WaitingForConfirmation, DeliveringProduct, ReturningChange. Each state performs its job and creates the next state object to send to the coordinator class.<\/p>\n Decorate with the Decorator Pattern<\/strong><\/span> The decorator pattern can aid in these situations. It is very simple: take existing functionality and add to it. This is accomplished by extending the original class and providing new functionality at run-time. Old clients continue to use the new object as they would an old one, and new clients will use both the old and new functionality.<\/p>\n When<\/span>: You can\u2019t change old classes, but you have to implement new behavior or state.<\/em><\/p>\n Why<\/span>: It offers an unintrusive way of adding new functionality.<\/em><\/p>\n A simple example is printing data. You print some information to the user as plain text, but you also want to provide the ability to print in HTML. The decorator pattern is one such solution that lets you keep both functionality.<\/p>\n Or, Accept a Visitor<\/strong> When<\/span>: A decorator is not appropriate and some extra complexity is acceptable.<\/em><\/p>\n Why<\/span>: To allow and organized approach to defining functionality for several objects but at the price of higher complexity.<\/em><\/p>\n Conclusion<\/strong><\/span> Design patterns help solve problems. As an implementation recommendation, never name your classes after the patterns. Instead, find the right names for the right abstractions. This helps you to better discern when you really need a pattern as opposed to just implementing one because you can.<\/p>\n Some may say that if you don\u2019t name your class with the pattern\u2019s name in it, then other developers will have a difficult time understanding your code. If it\u2019s hard to recognize a pattern, then the problem is in the pattern\u2019s implementation.<\/p>\n Use design patterns to solve your problems, but only if they fit. Do not abuse them. You\u2019ll find that a more simple solution befits a little problem; whereas, you\u2019ll discover that you need a pattern only after you implement a few other solutions.<\/p>\n If you\u2019re new to design patterns, I hope that this article has given you some idea as to how patterns can be helpful in your applications.<\/p>\n from internet<\/em><\/span><\/p>\n","protected":false},"excerpt":{"rendered":" Again, we have another article about Design Patterns. but this time it’s not the same :). There are plenty of articles that explain what design patterns are, and how to implement them; the web doesn\u2019t need yet another one of those articles! Instead, in this article, we will more discuss the when and why, rather…<\/p>\n
\nUse a Factory Pattern<\/strong>
\nThe factory pattern was invented to help programmers organize the information related to object creation. Objects sometimes have lot of constructor parameters; other times, they must be populated with default information immediately after their creation. These objects should be created in factories, keeping all the information regarding their creation and initialization contained within a single place.<\/p>\n
\n
\nThere are two frequently used patterns to retrieve information from a persistence layer or external data source.<\/p>\n
\nThis pattern defines a communication channel between a persistence solution and the business logic. For simpler applications, it can retrieve or recreate whole objects by itself, but object creation is the responsibility of factories in most complex applications. Gateways simply retrieve and persist raw data.<\/p>\n
\nThere are times when you can not (or do not want to) expose the knowledge of the persistence layer to your business classes. The proxy pattern is a good way to fool your business classes into thinking they are using already existing objects.<\/p>\n
\nThe repository pattern is very useful for implementing search methods and mini-query languages. It takes these queries and uses a gateway to obtain the data for a factory to produce the objects you need.<\/p>\n\n
\nA null object implements the same interface of your other objects, but the object\u2019s members return a neutral value. For example, a method that returns a string would return an empty string; another member returning a numeric value would return zero. This forces you to implement methods that do not return meaningful data, but you can use these objects without worrying about refused bequest or littering your code with null checks.<\/p>\n
\nThe simple and interesting active object has only one responsibility: keep a list of command objects and run them.<\/p>\n\n
\n
\nI am positive that you\u2019ve heard the big promise of object oriented programming: code reuse. Early adopters of OOP envisioned using universal libraries and classes in millions of different projects. Well, it never happened.<\/p>\n
\nThis pattern allows for the partial reuse of code. It\u2019s practical with multiple algorithms which only slightly differ from one another.<\/p>\n
\n
\nAs projects grow, it becomes increasingly difficult for external users to access our application. That\u2019s one reason to offer a well-defined entry point to the application or module in question. Other such reasons may include the desire to conceal the module\u2019s internal workings and structure.<\/p>\n
\nA facade is essentially an API \u2013 a nice and client-facing interface. When a client calls one of these nice methods, the facade delegates a series of calls to the classes it hides in order to provide the client with the required information or desired result.<\/p>\n
\nA null object implements the same interface as your other objects.<\/p>\n\n
\nThe observer pattern can be extended with a mediator pattern. This pattern takes two objects as parameters. The mediator subscribes itself to the first parameter, and when a change happens to the observed object, the mediator decides what to do on the second object.<\/p>\n
\n
\nSometimes, you need special objects that are unique in your application, and you want to ensure that all consumers can see any change made to these objects. You also want to prevent creating multiple instances of such objects for certain reasons, like long initialization time or problems with concurrent actions to some third party libraries.<\/p>\n
\nA singleton is an object having a private constructor and a public getInstance() method. This method ensures that only one instance of the object exists.<\/p>\n
\nAnother approach to singularity is the monostate design pattern. This solution uses a trick offered by object oriented programming languages. It has dynamic public methods which get or set the values of static private variables. This, in turn, ensures that all instances of such classes share the same values.<\/p>\n
\n
\nThe repository pattern is quite useful for implementing search methods\u2026<\/p>\n
\nThis is the simplest pattern ever invented. It only uses an interface. That\u2019s it, but there are several different implementations.<\/p>\n
\nThe adapter pattern simply creates a correspondence between the business logic and something else. We have already seen such a pattern in action: the gateway pattern.<\/p>\n
\nThis is a very complicated pattern. I personally do not like it because it is usually easier to take a different approach. But for those special cases, when other solutions fail, you can consider the bridge pattern.<\/p>\n
\n
\nConsider that you have a script with similar commands, and you want make a single call to run them. Wait! Didn\u2019t we already see something like this earlier? The active object pattern?<\/p>\n
\n
\nGateways only retrieve and persist raw data.<\/p>\n
\n
\nThere are times when you deploy classes or modules throughout an application, and you can\u2019t modify them without radically affecting the system. But, at the same time, you need to add new functionality that your users require.<\/p>\n
\nIf your problem of extending functionality is different \u2013 say, you have a complex tree-like structure of objects, and you want to add functionality to many nodes at once \u2013 a simple iteration is not possible, but a visitor might be a viable solution. The downside, however, is that a visitor pattern implementation requires modification to the old class if it wasn\u2019t designed to accept a visitor.<\/p>\n
\n
\nUse design patterns to solve your problems, but only if they fit.<\/p>\n