Design Patterns GoF & more in 3 Prog. Lang.

        Open left panel     
    
    

Creational DP (5)

    
    

Structural DP (7)

    
    

Behavioral DP (11)

    
    

Other DP (MVC,... )

    
    
    
        

Menu Panel

             Close     
    
    
Back         

Design Patterns GoF & more in 4 Languages

             
    

Category - Name / Description

UML OOP Diagram

My Notes

Sample Code

    
    
        

Menu Panel

             Close     
    
        

Menu Panel

     Close     
    
    
        

Design Patterns - Notes

        Open left panel              
    

Design Patterns - Notes

These are your (user) notes you have taken in each Design Pattern web-page

    
    
        

Menu Panel

             Close     
    
    
        

Contact Us

        Open left panel              
    

Contact Support

Web App Version 1.0.4 - 09-09-2020

Android App

iOS/iPadOS App & Windows 10 App - Coming Soon!


http://www.bestofficedesksetup.com

index2@bestofficedesksetup.com

Email Addreses/Web-Sites

Developer (Owner): L web Dev net - Polis

Tel/Fax/Street Address

Developer (Owner): L web Dev net - Polis

7 Apostolos Andreas Str,
P.O.Box 347,
Polis 8820,
Paphos District - (Greek) Cyprus - Europe

Social Networking with Us

Developer (Owner): L web Dev net - Polis

behancebehancefacebookflickrTumblrinmyspacePinterestStumble Upontwitterblogyou tubevimeoskype call

Polis Town - Index - Directory

The Paphos MarketPlace

Odysseas (Polis) Gallery - AG PHOTO WORLD Ltd
(Our Partner)

behancefacebookflickrTumblrinmyspacePinterestStumble Upontwitteryou tubefoursquare

Odysseas (Polis) Photo Gallery - Photography Services

    
    
        

Menu Panel

             Close     
    
    
        

Social Networking with us & Sharing

        Open left panel              
    

Contact Support

http://www.bestofficedesksetup.com

index2@bestofficedesksetup.com

Social Networking with Us

Developer (Owner): L web Dev net - Polis

behancebehancefacebookflickrTumblrinmyspacePinterestStumble Upontwitterblogyou tubevimeoskype call

Polis Town - Index - Directory

The Paphos MarketPlace

Odysseas (Polis) Gallery - AG PHOTO WORLD Ltd
(Our Partner)

behancefacebookflickrTumblrinmyspacePinterestStumble Upontwitteryou tubefoursquare

Odysseas (Polis) Photo Gallery - Photography Services

    
    
        

Menu Panel

             Close     
    
    
        

Design Patterns - Tutorials

        Open left panel              
    

Tutorials

    
        

GoF - What Is Design Pattern ?

In general, a pattern has four essential elements: 1. The pattern name is a handle we can use to describe a design problem, its solutions, and consequences in a word or two. Naming a pattern immediately increases our design vocabulary. It lets us design at a higher level of abstraction. Having a vocabulary for patterns lets us talk about them with our colleagues, in our documentation, and even to ourselves. It makes it easier to think about designs and to communicate them and their trade-offs to others. Finding good names has been one of the hardest parts of developing our catalog. 2. The problem describes when to apply the pattern. It explains the problem and its context. It might describe specific design problems such as how to represent algorithms as objects. It might describe class or object structures that are symptomatic of an inflexible design. Sometimes the problem will include a list of conditions that must be met before it makes sense to apply the pattern. 3. The solution describes the elements that make up the design, their relationships, responsibilities, and collaborations. The solution doesn't describe a particular concrete design or implementation, because a pattern is like a template that can be applied in many different situations. Instead, the pattern provides an abstract description of a design problem and how a general arrangement of elements (classes and objects in our case) solves it. 4. The consequences are the results and trade-offs of applying the pattern. Though consequences are often unvoiced when we describe design decisions, they are critical for evaluating design alternatives and for understanding the costs and benefits of applying the pattern. The consequences for software often concern space and time trade-offs. They may address language and implementation issues as well. Since reuse is often a factor in object-oriented design, the consequences of a pattern include its impact on a system's flexibility, extensibility, or portability. Listing these consequences explicitly helps you understand and evaluate them.
         
        

GoF Definitions

    

Creational Patterns Abstract Factory Provide an interface for creating families of related or dependent objects without specifying their concrete classes. Builder Separate the construction of a complex object from its representation so that the same construction process can create different representations. Factory Method Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. Prototype Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. Singleton Ensure a class only has one instance, and provide a global point of access to it. Structural Patterns Adapter Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces. Bridge Decouple an abstraction from its implementation so that the two can vary independently. Composite Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. Decorator Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. Facade Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. Flyweight Use sharing to support large numbers of fine-grained objects efficiently. Proxy Provide a surrogate or placeholder for another object to control access to it. Behavioral Patterns Chain of Responsibility Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. Command Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations. Interpreter Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language. Iterator Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. Mediator Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently. Memento Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later. Observer Define a one-to-many dependency between objects so that when one object changes state, all its dependants are notified and updated automatically. State Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. Strategy Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it. Template Method Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure. Visitor Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

    
    
        

GoF Rules of Thumb

    

1. Creational Patterns Sometimes creational patterns are competitors: there are cases when either Prototype or Abstract Factory could be used profitably. At other times they are complementory: Abstract Factory might store a set of Prototypes from which to clone and return product objects , Builder can use one of the other patterns to implement which components get built. Abstract Factory, Builder, and Prototypecan use Singleton in their implementation. Abstract Factory, Builder, and Prototype define a factory object that's responsible for knowing and creating the class of product objects, and make it a parameter of the system. Abstract Factory has the factory object producing objects of several classes. Builder has the factory object building a complex product incrementally using a correspondingly complex protocol. Prototype has the factory object (aka prototype) building a product by copying a prototype object. Abstract Factory classes are often implemented with Factory Methods, but they can also be implemented using Prototype. Abstract Factory can be used as an alternative to Facade to hide platform-specific classes. Builder focuses on constructing a complex object step by step. Abstract Factory emphasizes a family of product objects (either simple or complex). Builder returns the product as a final step, but as far as the Abstract Factory is concerned, the product gets returned immediately. Builder is to creation as Strategy is to algorithm. Builder often builds a Composite. Factory Methods are usually called within Template Methods. Factory Method: creation through inheritance. Prototype: creation through delegation. Often, designs start out using Factory Method(less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed. Prototype doesn't require subclassing, but it does require an Initialize operation. Factory Methodrequires subclassing, but doesn't require Initialize. Designs that make heavy use of the Compositeand Decorator patterns often can benefit from Prototype as well. 2. Structural Patterns Adapter makes things work after they're designed; Bridge makes them work before they are. Bridge is designed up-front to let the abstraction and the implementation vary independently. Adapter is retrofitted to make unrelated classes work together. Adapter provides a different interface to its subject. Proxy provides the same interface. Decorator provides an enhanced interface. Adapter changes an object's interface, Decoratorenhances an object's responsibilities. Decorator is thus more transparent to the client. As a consequence, Decorator supports recursive composition, which isn't possible with pure Adapters. Composite and Decorator have similar structure diagrams, reflecting the fact that both rely on recursive composition to organize an open-ended number of objects. Composite can be traversed with Iterator. Visitorcan apply an operation over a Composite. Composite could use Chain of Responsibility to let components access global properties through their parent. It could also use Decorator to override these properties on parts of the composition. It could use Observer to tie one object structure to another and State to let a component change its behavior as its state changes. Composite can let you compose a Mediator out of smaller pieces through recursive composition. Decorator lets you change the skin of an object. Strategy lets you change the guts. Decorator is designed to let you add responsibilities to objects without subclassing. Composite's focus is not on embellishment but on representation. These intents are distinct but complementary. Consequently, Composite and Decorator are often used in concert. Decorator and Proxy have different purposes but similar structures. Both describe how to provide a level of indirection to another object, and the implementations keep a reference to the object to which they forward requests. Facade defines a new interface, whereas Adapterreuses an old interface. Remember that Adaptermakes two existing interfaces work together as opposed to defining an entirely new one. Facade objects are often Singletons because only one Facade object is required. Mediator is similar to Facade in that it abstracts functionality of existing classes. Mediatorabstracts/centralizes arbitrary communication between colleague objects, it routinely "adds value", and it is known/referenced by the colleague objects. In contrast, Facade defines a simpler interface to a subsystem, it doesn't add new functionality, and it is not known by the subsystem classes. Abstract Factory can be used as an alternative to Facade to hide platform-specific classes. Whereas Flyweight shows how to make lots of little objects, Facade shows how to make a single object represent an entire subsystem. Flyweight is often combined with Composite to implement shared leaf nodes. Flyweight explains when and how State objects can be shared. 3. Behavioral Patterns Behavioral patterns are concerned with the assignment of responsibilities between objects, or, encapsulating behavior in an object and delegating requests to it. Chain of Responsibility, Command, Mediator, and Observer, address how you can decouple senders and receivers, but with different trade-offs. Chain of Responsibility passes a sender request along a chain of potential receivers. Command normally specifies a sender-receiver connection with a subclass. Mediator has senders and receivers reference each other indirectly. Observer defines a very decoupled interface that allows for multiple receivers to be configured at run-time. Chain of Responsibility can use Command to represent requests as objects. Chain of Responsibility is often applied in conjunction with Composite. There, a component's parent can act as its successor. Command and Memento act as magic tokens to be passed around and invoked at a later time. In Command, the token represents a request; in Memento, it represents the internal state of an object at a particular time. Polymorphism is important to Command, but not to Mementobecause its interface is so narrow that a memento can only be passed as a value. Command can use Memento to maintain the state required for an undo operation. MacroCommands can be implemented with Composite. A Command that must be copied before being placed on a history list acts as a Prototype. Interpreter can use State to define parsing contexts. The abstract syntax tree of Interpreter is a Composite (therefore Iterator and Visitor are also applicable). Terminal symbols within Interpreter's abstract syntax tree can be shared with Flyweight. Iterator can traverse a Composite. Visitor can apply an operation over a Composite. Polymorphic Iterators rely on Factory Methods to instantiate the appropriate Iterator subclass. Mediator and Observer are competing patterns. The difference between them is that Observerdistributes communication by introducing "observer" and "subject" objects, whereas a Mediator object encapsulates the communication between other objects. We've found it easier to make reusable Observers and Subjects than to make reusable Mediators. On the other hand, Mediator can leverage Observer for dynamically registering colleagues and communicating with them. Mediator is similar to Facade in that it abstracts functionality of existing classes. Mediatorabstracts/centralizes arbitrary communication between colleague objects, it routinely "adds value", and it is known/referenced by the colleague objects (i.e. it defines a multidirectional protocol). In contrast, Facade defines a simpler interface to a subsystem, it doesn't add new functionality, and it is not known by the subsystem classes (i.e. it defines a unidirectional protocol where it makes requests of the subsystem classes but not vice versa). Memento is often used in conjunction with Iterator. An Iterator can use a Memento to capture the state of an iteration. The Iterator stores the Memento internally. State is like Strategy except in its intent. Flyweight explains when and how State objects can be shared. State objects are often Singletons. Strategy lets you change the guts of an object. Decorator lets you change the skin. Strategy is to algorithm. as Builder is to creation. Strategy has 2 different implementations, the first is similar to State. The difference is in binding times (Strategy is a bind-once pattern, whereas State is more dynamic). Strategy objects often make good Flyweights. Strategy is like Template Method except in its granularity. Template Method uses inheritance to vary part of an algorithm. Strategy uses delegation to vary the entire algorithm. The Visitor pattern is like a more powerful Command pattern because the visitor may initiate whatever is appropriate for the kind of object it encounters.

    
    
        

GoF FAQ

    

1. Builder v/s Decorator 2. Template Method v/s Strategy 3. Chain of Responsibility v/s Decorator 4. State v/s Strategy 5. Proxy v/s Decorator 6. Class Adapter v/s Object Adapter 7. Proxy v/s Decorator v/s Adapter v/s Bridge 8. Decorator v/s Bridge 9. Bridge v/s Strategy 10. Mediator v/s Facade 11. Prototype v/s Flyweight 12. In Java, how will you prevent cloning of a Singleton object? 13. What are Software Design Principles? 14. Open Close Principle 15. Dependency Inversion Principle 16. Interface Segregation Principle 17. Single Responsibility Principle 18. Liskov's Substitution Principle 1. Builder v/s Decorator Builder Pattern makes it easy to construct an object which is extensible in independent directions at construction time, while the Decorator Pattern lets you add extensions to functionality to an object after construction time. Using the decorator pattern to construct objects is bad because it leaves the object in an inconsistent (or at least incorrect) state until all the required decorators are in place. 2. Template Method v/s Strategy "Template method pattern: compile-time algorithm selection by subclassing" With the Template method pattern this happens at compile-time by subclassing the template. Each subclass provides a different concrete algorithm by implementing the template's abstract methods. When a client invokes methods of the template's external interface the template calls its abstract methods (its internal interface) as required to invoke the algorithm. "Strategy pattern: run-time algorithm selection by containment" The Strategy pattern allows an algorithm to be chosen at runtime by containment. The concrete algorithms are implemented by separate classes or functions which are passed to the strategy as a parameter to its constructor or to a setter method. Which algorithm is chosen for this parameter can vary dynamically based on the program's state or inputs. 3. Chain of Responsibility v/s Decorator Chain of Responsibility allows us to process the request and pass it on to the next object in the chain. This give us the ability to break the chain anytime there by allowing only certain hooks to process the request. However, in case of Decorator, it is difficult to prevent other processors/hooks from processing the request. 4. State v/s Strategy The implementation of the State pattern builds on the Strategy pattern. The difference between State and Strategy is in the intent. With Strategy, the choice of algorithm is fairly stable. With State, a change in the state of the "context" object causes it to select from its "palette" of Strategy objects. 5. Proxy v/s Decorator Decorator and Proxy have different purposes but similar structures. Both describe how to provide a level of indirection to another object, and the implementations keep a reference to the object to which they forward requests. 6. Class Adapter v/s Object Adapter Class Adapter uses inheritance and can only wrap a class. It cannot wrap an interface since by definition it must derive from some base class. Object Adapter uses composition and can wrap classes or interfaces, or both. It can do this since it contains, as a private, encapsulated member, the class or interface object instance it wraps. 7. Proxy v/s Decorator v/s Adapter v/s Bridge Proxy, Decorator, Adapter, and Bridge are all variations on "wrapping" a class. But their uses are different. - Proxy could be used when you want to lazy-instantiate an object, or hide the fact that you're calling a remote service, or control access to the object. - Decorator is also called ""Smart Proxy."" This is used when you want to add functionality to an object, but not by extending that object's type. This allows you to do so at runtime. - Adapter is used when you have an abstract interface, and you want to map that interface to another object which has similar functional role, but a different interface. - Bridge is very similar to Adapter, but we call it Bridge when you define both the abstract interface and the underlying implementation. I.e. you're not adapting to some legacy or third-party code, you're the designer of all the code but you need to be able to swap out different implementations. - Facade is a higher-level (read: simpler) interface to a subsystem of one or more classes. Suppose you have a complex concept that requires multiple objects to represent. Making changes to that set of objects is confusing, because you don't always know which object has the method you need to call. That's the time to write a Facade that provides high-level methods for all the complex operations you can do to the collection of objects. Example: a Domain Model for a school section, with methods like countStudents(), reportAttendance(), assignSubstituteTeacher(), and so on. 8. Decorator v/s Bridge The Decorator should match the interface of the object you're decorating. i.e. it has the same methods, and permits interception of the arguments on the way in, and of the result on the way out. You can use this to provide additional behaviour to the decorated object whilst maintaining the same interface/contract. Note that the interface of the Decorator can provide additional functionality to create a more useful object. The Bridge has no such constraint. The client-facing interface can be different from the underlying component providing the implementation, and thus it bridges between the client's interface, and the actual implementation (which may not be client-friendly, subject to change etc.) 9. Bridge v/s Strategy The UML class diagram for the Strategy pattern is the same as the diagram for the Bridge pattern. However, these two design patterns aren't the same in their intent. While the Strategy pattern is meant for behavior, the Bridge pattern is meant for structure. The coupling between the context and the strategies is tighter than the coupling between the abstraction and the implementation in the Bridge pattern. 10. Mediator v/s Facade In the implementation of mediator pattern, subsystem or peers components are aware of the mediator and that interact with it. In the case of facade pattern, subsystems are not aware of the existence of facade. Only facade talks to the subsystems. 11. Prototype v/s Flyweight In Prototype objects' creation go through cloning, it ease object's creation. By making a request for cloning we create new cloned object each time. In Flyweight by making a request we try to reuse as much objects as possible by sharing them. New required object will be created if we don't find such one. It's being done for resource optimization. 12. In Java, how will you prevent cloning of a Singleton object? The clone() method by default is protected, so no class (except those in the same package) would be able to call it on that Singleton instance. Plus, if this Singleton does not implement Cloneable, then even if this method is called, it will give a runtime exception. Plus, the constructor being private, we won't be able to subclass it and thus allow for its cloning. However, if the Singleton class extends another class that does support cloning, it is possible to violate the design principles of the singleton. So, to be absolutely positively 100% certain that a singleton really is a singleton, we must extend the Cloneable interface add a clone() method of our to throw a CloneNotSupportedException. 13. What are Software Design Principles? Software design principles represent a set of guidelines that helps us to avoid having a bad design. The design principles are associated to Robert Martin who gathered them in "Agile Software Development: Principles, Patterns, and Practices". According to Robert Martin there are 3 important characteristics of a bad design that should be avoided: Rigidity - It is hard to change because every change affects too many other parts of the system. Fragility - When you make a change, unexpected parts of the system break. Immobility - It is hard to reuse in another application because it cannot be disentangled from the current application. 14. Open Close Principle "Software entities like classes, modules and functions should be open for extension but closed for modifications." OPC is a generic principle. You can consider it when writing your classes to make sure that when you need to extend their behavior you don't have to change the class but to extend it. The same principle can be applied for modules, packages, libraries. If you have a library containing a set of classes there are many reasons for which you'll prefer to extend it without changing the code that was already written (backward compatibility, regression testing). This is why we have to make sure our modules follow Open Closed Principle. When referring to the classes Open Close Principle can be ensured by use of Abstract Classes and concrete classes for implementing their behavior. This will enforce having Concrete Classes extending Abstract Classes instead of changing them. Some particular cases of this are Template Pattern and Strategy Pattern." 15. Dependency Inversion Principle " High-level modules should not depend on low-level modules. Both should depend on abstractions." " Abstractions should not depend on details. Details should depend on abstractions." Dependency Inversion Principle states that we should decouple high level modules from low level modules, introducing an abstraction layer between the high level classes and low level classes. Further more it inverts the dependency: instead of writing our abstractions based on details, the we should write the details based on abstractions. Dependency Inversion or Inversion of Control are better know terms referring to the way in which the dependencies are realized. In the classical way when a software module(class, framework, etc) need some other module, it initializes and holds a direct reference to it. This will make the 2 modules tight coupled. In order to decouple them the first module will provide a hook(a property, parameter, etc) and an external module controlling the dependencies will inject the reference to the second one. By applying the Dependency Inversion the modules can be easily changed by other modules just changing the dependency module. Factories and Abstract Factories can be used as dependency frameworks, but there are specialized frameworks for that, known as Inversion of Control Container." 16. Interface Segregation Principle " Clients should not be forced to depend upon interfaces that they don't use." This principle teaches us to take care how we write our interfaces. When we write our interfaces we should take care to add only methods that should be there. If we add methods that should not be there the classes implementing the interface will have to implement those methods as well. For example if we create an interface called Worker and add a method lunch break, all the workers will have to implement it. What if the worker is a robot? As a conclusion Interfaces containing methods that are not specific to it are called polluted or fat interfaces. We should avoid them. 17. Single Responsibility Principle " A class should have only one reason to change." In this context a responsibility is considered to be one reason to change. This principle states that if we have 2 reasons to change for a class, we have to split the functionality in two classes. Each class will handle only one responsibility and on future if we need to make one change we are going to make it in the class which handle it. When we need to make a change in a class having more responsibilities the change might affect the other functionality of the classes. Single Responsibility Principle was introduced Tom DeMarco in his book Structured Analysis and Systems Specification, 1979. Robert Martin reinterpreted the concept and defined the responsibility as a reason to change. 18. Liskov's Substitution Principle "Derived types must be completely substitutable for their base types." This principle is just an extension of the Open Close Principle in terms of behavior meaning that we must make sure that new derived classes are extending the base classes without changing their behavior. The new derived classes should be able to replace the base classes without any change in the code. Liskov's Substitution Principle was introduced by Barbara Liskov in a 1987 Conference on Object Oriented Programming Systems Languages and Applications, in Data abstraction and hierarchy

    

Refactoring & Best Practises

    
        

OOP, Inheritance, Composition and Aggregation

    

Introducing Object-Oriented Programming - Summary

The main features of object-oriented programming, or OOP for short, are • Encapsulation • Abstraction • Inheritance • Polymorphism Encapsulation Encapsulation is all about data privacy. The contents of a class – it’s state – is kept private and is only accessible to the code inside the class. Abstraction Along with encapsulation you want to make your class as simple as possible. You don’t want people using it to have to do some complex series of steps, or to know too much about the internal workings of your class to use it. This is where abstraction comes in. Inheritance Inheritance allows one class to derive from another. This way you only have to write the specific code that changed from your base class. A parent class is called a base class and a class that uses another as a basis is called a subclass or derived class. Polymorphism In OOP it is sometimes necessary to alter subclasses. Polymorphism can go hand in hand with inheritance. For example, we might have a Shape class that Circle, Square, and Triangle are derived from. The Shape class has a draw() method that the other classes implement drawing different shapes onscreen. Why Should You Use OOP? OOP allows us to create code that is • Data hiding • Reusable • Easier to code and test separately Data Hiding The information is stored inside the classes. The data held in these classes can only be accessed through methods exposed by the class. These methods make up the interface, that is, how the class is accessed by the other code in your game. Reusable Much like functions, classes can be reused by multiple games. You can build up quite a big library of classes over your years programming. Each one of these classes can be used in subsequent projects. Easier to Code and Test Separately On a larger project the workload can be divided between developers. With the workload divided the programmers can write the classes and test them in isolation from the rest of the game. By writing and testing the classes separately you increase the chance of reusability because the classes do not rely on each other and can work independently. EXAMPLES In Python we would describe the ball class like this: class Ball: A class is defined using the class keyword. You must give your class a name. Something short and meaningful is perfect, but avoid plurals. If you have a collection of items (like balls) use BallCollection rather than Balls for the name of the class. Methods are defined as you would a function with the def keyword, the method/function name, and the parameter list. The major difference is the use of the ‘self’ keyword as the first entry of the parameter list. Earlier I mentioned that the member fields are per object. The ‘self’ keyword is used because Python passes in a reference to the object being used for that operation. Whereas the data is different for each object, the code is not. It is shared between all instances of the class. This means that the same piece of code that updates a ball is used by all instances of the Ball class. THE FIRST ARGUMENT IN A CLASS METHOD’S PARAMETER LIST IS ALWAYS ‘self’ if __name__ == '__main__': Python knows the name of each module – remember that a Python file that contains functions and/or class definitions is a module – that it is running because it is the name of the file without the ‘.py’ extension. When you execute a Python script using one of the following methods: $ ./myprogram.py $ python3 myprogram.py The entry file is given a special name, so instead of ‘myprogram,’ the name of the entry point file is ‘__main__’. We can use this to our advantage because it means that we can put our classes in separate files; import them as required; and more importantly, test them in isolation. This is the beauty of OOP: the fact that you can take small objects, test them in isolation, and then combine them into a much larger program. Constructors A constructor is a special method that is called when an object is instantiated. The method isn’t called using the conventional calling method with the object, a dot, and the method name. You’ve actually been calling the constructor when you created the ball: ball = Ball() Although you didn’t explicitly create a constructor, Python creates one for you. It doesn’t contain any code and it would look something like this (don’t ever do this, it’s not worth it; just let Python create one for you behind the scenes): def __init__(self): pass The double underscores before and after a name, like __init__, are special method names used by Python. When you want to do something different from the default behavior you will override the default method with your own. Python describes these names as ‘magic’ and as such you should never invent your own and only use them as documented. Like when we want to create our own constructors. In Python the constructor method is called init. It takes at least one parameter, the ‘self’ keyword. SOLID Acronym Classes describe attributes and methods that describe and perform actions, respectively, of an abstract data structure. There is an acronym that describes five principles of object design. For our games, we will try to adhere to these principles: • Single responsibility • Open-closed principle • Liskov substitution • Interface segregation • Dependency inversion Single Responsibility Each class should have a single responsibility and that responsibility should be contained within the class. Open-Closed Principle Your class should be thoroughly tested (hint: name ==‘ main ’) and should be closed from further expansion. It’s OK to go in and fix bugs, but your existing classes shouldn’t have additional functionality added to them because that will introduce new bugs. You can achieve this in one of two ways: extension or composition. With extension, you are extending the base class and changing the existing functionality of a method. With composition, you encapsulate the old class inside a new class and use the same interface to change how the caller interacts with the internal class. A class interface is just the list of methods (the actions) that can be performed on the class. Liskov Substitution This is by far the trickiest of all the SOLID principles. The idea behind this principle is that when extending a class the subclass should act no different than the class it extends. This is also known as the substitutability of a class. Interface Segregation Interface segregation means that you should code to the interface, rather than the implementation. There are other ways to achieve this in other OOP languages, but Python uses something called Duck Typing. In certain programming languages like Java, C#, and C++, an object’s type is used to determine if it is suitable. In Python, however, suitability is determined by the presence of the method or property rather than the type of the object. If it walks like a duck and it quacks like a duck, it’s a duck Python will try and call a method on an object with the same name and parameters even if they’re not the same object. Dependency Inversion Last is dependency inversion. Dependency inversion is a form of decoupling where higher-level modules (classes) should not depend on lower-level modules (classes). They should instead both depend on abstractions. Second, abstractions should not depend on details. Details should depend on abstractions. Conclusion This has been a short introduction to OOP. By this point you should understand the following: • Attributes are member fields and contain data that describes the class. • Methods are functions that belong to a class that perform actions on the class. • Self is used to reference. • A constructor can be used to initialize member fields when the object instance is created. • Python uses Duck Typing; when you see a bird that walks like a duck, swims like a duck, and quacks like a duck … it’s a duck.

Inheritance, Composition, and Aggregation - Summary

When most people learn about object-oriented programming, they learn three things: • Objects have attributes (data) that contain the object’s state. • Methods that control access (change or view) theobject’s state. • Objects can be extended using a technique called inheritance. There are others, but those are the three main things that people remember about their first introduction to object-oriented programming. Most people fixate on that last one: object extension by inheritance. That’s true in a lot of cases, but there are ways that objects can be extended using techniques called composition and aggregation. This section will introduce the three methods of object extension. Inheritance USE THE NEWER MyClass(object) SYNTAX WHEN DEFINING CLASSES. A base class contains the basic level of functionality that is required to perform a given set of actions. It can contain methods that are placeholders for actions that will be implemented by a child class. A child class is any class that derives from another class. In actuality, every class you create is a child class of the Python base ‘object’ class. Programming to the interface means that you don’t need to worry about the internal workings of the object; you just need to know what methods are available. You must always call your base class’s constructor before you write any other code in your derived class’s constructor. This is especially true if you are creating a base class with lots of functionality and inheriting from it. Make sure you call the base class’s constructor! Composition Composition is the containment of one or more objects inside another. With composition, the contained objects’ creation and destruction are controlled by the container object. The container object generally acts as a controller for the contained objects. Aggregation Aggregation is, conceptually, much like composition. A container object has a link to other objects and it manipulates them in some form, through a method or methods. However, the big difference is that the creation and destruction of the objects are handled elsewhere outside of the class. With aggregation, the container class must not delete objects that it uses. Conclusion Python allows for standard OOP techniques but offers its own unique twist: duck typing. By programming to the interface, we can ensure that our classes can be written independently of each other. PROGRAM TO THE INTERFACE TO KEEP YOUR CLASSES SMALL AND NIMBLE

    
    
        

Refactoring

    

Developers must first seek to understand how to code before they themselves may refactor code effectively.

    

What is refactoring? A key theme in refactoring code is addressing issues within the internal structure of code while not altering the external behavior of the program being refactored. In some cases, this can mean introducing internal structure where it previously wasn't intentional or thought about before. Refactoring as a process improves the design of code after it is written. While design is a critical phase of the software engineering process, it is often disregarded (not least in PHP); in addition to this, maintaining the structure of code over the long-term requires a continued understanding of the design of software. If a developer takes up a project without understanding how it was originally designed, they may develop upon it in a very crude fashion. In Extreme Programming (XP), a phrase known as Refactor Mercilessly is used, it is selfexplanatory. In XP, refactoring is proposed as a mechanism to keep software design as simple as possible and to avoid needless complexity. As is stated in the rules of XP: Make sure everything is expressed once and only once. In the end it takes less time to produce a system that is well groomed.??????????????

    
    
        

Best Practises using Design Patterns

    

1.7 How to Select a Design Pattern

Design Patterns: How to Select a Design Pattern

With more than 20 design patterns in the catalog to choose from, it might be hard to find the one that addresses a particular design problem, especially if the catalog is new and unfamiliar to you. Here are several different approaches to finding the design pattern that's right for your problem: • Consider how design patterns solve design problems. Section 1.6 discusses how design patterns help you find appropriate objects, determine object granularity, specify object interfaces, and several other ways in which design patterns solve design problems. Referring to these discussions can help guide your search for the right pattern. • Scan Intent sections. Section 1.4 (page 8) lists the Intent sections from all the patterns in the catalog. Read through each pattern's intent to find one or more that sound relevant to your problem. You can use the classification scheme presented in Table 1.1 (page 10) to narrow your search. • Study how patterns interrelate. Figure 1.1 (page 12) shows relationships between design patterns graphically. Studying these relationships can help direct you to the right pattern or group of patterns. • Study patterns of like purpose. The catalog (page 79) has three chapters, one for creational patterns, another for structural patterns, and a third for behavioral patterns. Each chapter starts off with introductory comments on the patterns and concludes with a section that compares and contrasts them. These sections give you insight into the similarities and differences between patterns of like purpose. • Examine a cause of redesign. Look at the causes of redesign starting on page 24 to see if your problem involves one or more of them. Then look at the patterns that help you avoid the causes of redesign. • Consider what should be variable in your design. This approach is the opposite of focusing on the causes of redesign. Instead of considering what might force a change to a design, consider what you want to be able to change without redesign. The focus here is on encapsulating the concept that varies, a theme of many design patterns. Table 1.2 lists the design aspect(s) that design patterns let you vary independently, thereby letting you change them without redesign.

    

1.8 How to Use a Design Pattern

Design Patterns: How to Use a Design Pattern

Once you've picked a design pattern, how do you use it? Here's a step-by-step approach to applying a design pattern effectively: 1 . Read the pattern once through for an overview. Pay particular attention to the Applicability and Consequences sections to ensure the pattern is right for your problem. 2. Go back and study the Structure, Participants, and Collaborations sections. Make sure you understand the classes and objects in the pattern and how they relate to one another. 3. Look at the Sample Code section to see a concrete example of the pattern in code. Studying the code helps you learn how to implement the pattern. 4. Choose names for pattern participants that are meaningful in the application context. The names for participants in design patterns are usually too abstract to appear directly in an application. Nevertheless, it's useful to incorporate the participant name into the name that appears in the application. That helps make the pattern more explicit in the implementation. For example, if you use the Strategy pattern for a text compositing algorithm, then you might have classes SimpleLayoutStrategy or TeXLayoutStrategy. 5. Define the classes. Declare their interfaces, establish their inheritance relationships, and define the instance variables that represent data and object references. Identify existing classes in your application that the pattern will affect, and modify them accordingly. 6. Define application-specific names for operations in the pattern. Here again, the names generally depend on the application. Use the responsibilities and collaborations associated with each operation as a guide. Also, be consistent in your naming conventions. For example, you might use the "Create-" prefix consistently to denote a factory method. 7. Implement the operations to carry out the responsibilities and collaborations in the pattern. The Implementation section offers hints to guide you in the implementation. The examples in the Sample Code section can help as well. These are just guidelines to get you started. Over time you'll develop your own way of working with design patterns. No discussion of how to use design patterns would be complete without a few words on how not to use them. Design patterns should not be applied indiscriminately. Often they achieve flexibility and variability by introducing additional levels of indirection, and that can complicate a design and/or cost you some performance. A design pattern should only be applied when the flexibility it affords is actually needed. The Consequences sections are most helpful when evaluating a pattern's benefits and liabilities.

    
    
        

Other FAQ for Design Patterns

    

1. Which design pattern do you like the most? It depends on many factors, such as the context, situation, demand, constraints, and so on. If you know about all the patterns, you have more options to choose from. 2. Why should developers use design patterns? They are reusable solutions for software design problems that appear repeatedly in real-world software development. 3. How are libraries (or frameworks) similar/different from design patterns? They are not design patterns. They provide the implementations that you can use directly in your application. But they can use the concept of the patterns in those implementations. 4. If no particular pattern is 100% suitable for my problem, how should I proceed? An infinite number of problems cannot be solved with a finite number of patterns, for sure. But if you know these common patterns and their trade-offs, you can pick a close match. No one prevents you from using your own pattern for your own problem, but you have to tackle the risk. 5. What are the differences between class patterns and object patterns? In general, class patterns focus on static relationship but object patterns can focus on dynamic relationships. As name suggests, class patterns focus on classes and its subclasses and object patterns focus on the objects relationships. As per GoF, these patterns can be further differentiated in Table A-1.

6. Can I combine two or more patterns in an application? Yes. In real-world scenarios, this type of activity is common. 7. Do these patterns depend on a particular programming language? Programming languages can play an important role. But the basic ideas are same, patterns are just like templates and they give you some idea in advance of how you can solve a particular problem. In this book, I primarily focused on object-oriented programming with the concept of reuse. But instead of any object-oriented programming language, suppose you have chosen some other language like C. In that case, you may need to think about the core object-oriented principles such as inheritance, polymorphism, encapsulation, abstraction, and so on, and how to implement them. So, the choice of a particular language is always important because it may have specialized features that can make your life easier. 8. Do you suggest any general advice before I jump into the topics? I always follow the footsteps of my seniors and teachers who are experts in this field. And the following are general suggestions from them. • Program to a supertype(Abstract class/Interface), not an implementation. • Prefer composition over inheritance. • Try to make a loosely coupled system. • Segregate the code that is likely to vary from the rest of your code. • Encapsulate what varies.

    
    
        

Anti-Patterns

    

What Is an Antipattern?

In real-world application development, you may follow approaches that are very attractive at first, but in the long run, they cause problems. For example, you try to do a quick fix to meet a delivery deadline, but if you are not aware of the potential pitfalls, you may pay a big price. Antipatterns alert you about common mistakes that lead to a bad solution. Knowing them helps you take precautionary measures. The proverb “prevention is better than cure” very much fits in this context. Note Antipatterns alert you to common mistakes by describing how attractive approaches can make your life difficult in future. At the same time, they suggest alternate solutions that may seem tough or ugly at the beginning but ultimately help you build a better solution. In short, antipatterns identify problems with established practices and they can map general situations to a specific class of highly productive solutions. They can also provide better plans to reverse some bad practices and make healthy solutions. And with the launch of the classic text Design Patterns: Elements of Reusable Object−Oriented Software by the Gang of Four, design patterns became extremely popular. Undoubtedly, these great design patterns helped (and are still helping) programmers to develop the high-quality software. But people started noticing the negative impacts also. A common example is that many developers wanted to show their expertise without the true evaluation or the consequences of these patterns in their specific domains. As an obvious side effect, patterns were implanted in the wrong context, which produced low-quality software, and ultimately caused big penalties to the developers and their companies. So, the software industry needed to focus on the negative consequences of these mistakes, and eventually, the idea of antipatterns evolved.

Examples of Antipatterns

The following are some examples of the antipatterns and the concepts/mindsets behind them. • Over Use of Patterns: Developers may try to use patterns at any cost, regardless of whether it is appropriate or not. • God Class: A big object that tries to control almost everything with many unrelated methods. An inappropriate use of the mediator pattern may end up with this antipattern. • Not Invented Here: I am a big company and I want to build everything from scratch. Although there is already a library available that was developed by a smaller company, I’ll not use that. I will make everything of my own and once it is developed, I’ll use my brand value to announce, “Hey Guys. The ultimate library is launched for you.” • Zero Means Null: A common example includes developers who think that no one wants to be at latitude zero, longitude zero. Another common variation is when a programmer uses :1, 999 or anything like that to represent an inappropriate integer value. Another erroneous use case is observed when a user treats “09/09/9999” as a null date in an application. So, in these cases, if the user needs to have the numbers :1,999 or the date “09/09/9999”, he is unable to get them. • Golden Hammer: Mr. X believes that technology T is always best. So, if he needs to develop a new system (that demands new learning), he still prefers T, even if it is inappropriate. He thinks, “I do not need to learn any more technology if I can somehow manage it with T.” • Management by Numbers: The greater the number of commits, the greater the number of lines of code, or the greater the number of defects fixed are the signs of a great developer. Bill Gates said, “Measuring programming progress by lines of code is like measuring aircraft building progress by weight.” • Shoot the Messenger: You are already under pressure and the program deadline is approaching. There is a smart tester who always finds typical defects that are hard to fix. So, at this stage, you do not want to involve him because he will find more defects and the deadline may be missed. • Swiss Army Knife: Demand a product that can serve the customer’s every need. Or make a drug that cures all illnesses. Or design software that serves a wide range of customers with varying needs. It does not matter how complex the interface is. • Copy and Paste Programming: I need to solve a problem but I already have a piece of code to deal with a similar situation. So, I can copy the old code that is currently working and start modifying it if necessary. But when you start from an existing copy, you essentially inherit all the potential bugs associated with it. Also, if the original code needs to be modified in the future, you need to implement the modification in multiple places. This approach also violates the Don’t Repeat Yourself (DRY) principle. • Architects Don’t Code: I am an architect. My time is valuable. I’ll only show paths or give a great lecture on coding. There are enough implementers who should implement my idea. Architects Play Golf is a sister of this antipattern. • Hide and Hover: Do not expose all edits or delete links until he/she hovers the element. • Disguised Links and Ads: Earn revenue when users click a link or an advertisement, but they cannot get what they want. Note: You may also notice that the concept of antipatterns is not limited to object-oriented programming.

Types of Antipatterns

Antipatterns can belong in more than one category. Even a typical antipattern can belong in more than one category. The following are some common classifications. • Architectural antipatterns: The Swiss Army Knife antipattern is an example in this category. • Development antipatterns: The God Class and Over Use of Patterns are examples in this category. • Management antipatterns: The Shoot the Messenger antipattern falls in this category. • Organizational antipatterns: Architects Don’t Code and Architects Play Golf are examples in this category. • User Interface antipatterns: Examples include Disguised Links and Ads. Note D isguised Links and Ads are also called as dark patterns.

Q & A Session

1. How are antipatterns related to design patterns? With design patterns, you reuse the experiences of others who came before you. When you start blindly using those concepts for the sake of use only, you fall into the traps of reuse of recurring solutions. This can lead you to a bad situation. And then you learn that your return on investment keeps decreasing but maintenance costs keep increasing. The apparently easy and standard solutions (or patterns) may cause more problems for you in the future. 2. A design pattern may turn into an antipattern. Is this correct? Yes. If you apply a design pattern in the wrong context, that can cause more trouble than the problem it solves. Eventually it will turn into an antipattern. So, understanding the nature and context of the problem is very important. 3. Antipatterns are related to software developers only. Is this correct? No. The usefulness of an antipattern is not limited to developers; it may be applicable to others also; for example, antipatterns are useful to managers and technical architects also. 4. Even if you do not get much benefit from antipatterns now, they can help you adapt new features easily with fewer maintenance costs in future. Is this correct? Yes. 5. What are the probable causes of antipatterns? It can come from various sources/mindsets. The following are a few common examples. • “We need to deliver the product as soon as possible.” • “We do not need to analyze the impact right now.” • “I am an expert of reuse. I know design patterns very well.” • “We will use the latest technologies and features to impress our customers. We do not need to care about legacy systems.” • “More complicated code will reflect my expertise on the subject.” 6. Discuss some symptoms of antipatterns. In object-oriented programming, the most common symptom is your system cannot easily adapt a new feature. Also, maintenance costs are keep increasing. You may also notice that you have lost the power of key object-oriented features like inheritance, polymorphism, and so forth. Apart from these, you may notice some/all of the following symptoms. • Use of global variables • Code duplication • Limited/no reuse of code • One big class (God Class) • A large number of parameterless methods, etc. 7. What is the remedy if you detect an antipattern? You may need to follow a refactored and better solution. For example, the following are some solutions for avoiding antipatterns. Golden Hammer: You may try to educate Mr. X through proper training. Zero Means Null: You can use an additional boolean variable to indicate the null value properly. Management by Numbers: Numbers are good if you use them wisely. You cannot judge the ability of a programmer by the number of defects he/she fixes per week. The quality is also important. A typical example includes fixing a simple UI layout is much easy compared to fix a critical memory leak in the system. Consider another example. “More number of tests are passing” does not indicate that your system is more stable unless the tests exercise different code paths/branches. Shoot the Messenger: Welcome the tester and involve him immediately. He can find typical defects early, and you can avoid last-moment surprises. Copy and Paste Programming: Instead for searching a quick solution, you can refactor your code. You can also make a common place to maintain the frequently used methods to avoid duplicates and provide easier maintenance. Architects Don’t Code: Involve architects in parts of the implementation phase. This can help both the organization and the architects. This activity can give them a clearer picture about the true functionalities of the product. 8. What do you mean by refactoring? In the coding world, the term refactoring means improving the design of existing code without changing the external behavior of the system/application. This process helps you get more readable code. At the same time, the code should be more adaptable to new requirements (or change requests) and they should be more maintainable.

    
    
    
        

Menu Panel

             Close