Design patterns the gang of four book pdf




















The subset C's closest alternative would be to create a single global struct. This had the lack of clarity as to where this object was instantiated, as well as not guaranteeing the existence of the object. Take, for example, the situation of another developer using your singleton inside the constructor of their object.

Then, yet another developer decides to create an instance of the second class in the global scope. If you had simply used a global variable, the order of linking would then matter. Since your global will be accessed, possibly before main begins executing, there is no definition as to whether the global is initialized, or the constructor of the second class is called first. This behavior can then change with slight modifications to other areas of code, which would change order of global code execution.

Such an error can be very hard to debug. But, with use of the singleton, the first time the object is accessed, the object will also be created. You now have an object which will always exist, in relation to being used, and will never exist if never used. A second common use of this class is in updating old code to work in a new architecture. Since developers may have used globals liberally, moving them into a single class and making it a singleton, can be an intermediary step to bring the program inline to stronger object oriented structure.

Note: In the above example, the first call to Singleton::GetInstance will initialize the singleton instance. This example is for illustrative purposes only; for anything but a trivial example program, this code contains errors. Convert the interface of a class into another interface that clients expect.

Adapter lets classes work together that couldn't otherwise because of incompatible interfaces. The Bridge Pattern is used to separate out the interface from its implementation. Doing this gives the flexibility so that both can vary independently. Composite lets clients treat individual objects and compositions of objects uniformly. The Composite pattern can represent both the conditions. In this pattern, one can develop tree structures for representing part-whole hierarchies. The decorator pattern helps to attach additional behavior or responsibilities to an object dynamically.

Decorators provide a flexible alternative to subclassing for extending functionality. If your application does some kind of filtering, then Decorator might be good pattern to consider for the job. The Facade Pattern hides the complexities of the system by providing an interface to the client from where the client can access the system on a unified interface.

Facade defines a higher-level interface that makes the subsystem easier to use. For instance making one class method perform a complex process by calling several other classes. The pattern for saving memory basically by sharing properties of objects. Imagine a huge number of similar objects which all have most of their properties the same. It is natural to move these properties out of these objects to some external data structure and provide each object with the link to that data structure.

The Proxy Pattern will provide an object a surrogate or placeholder for another object to control access to it. It is used when you need to represent a complex object with a simpler one.

If creation of an object is expensive, it can be postponed until the very need arises and meanwhile a simpler object can serve as a placeholder. This technique is known more widely as a Mixin. Mixins are described in the literature to be a powerful tool for expressing abstractions [ citation needed ].

Interface-based programming is closely related with Modular Programming and Object-Oriented Programming, it defines the application as a collection of inter-coupled modules interconnected and which plug into each other via interface.

Modules can be unplugged, replaced, or upgraded, without the need of compromising the contents of other modules. The total system complexity is greatly reduced. Interface Based Programming adds more to modular Programming in that it insists that Interfaces are to be added to these modules. The entire system is thus viewed as Components and the interfaces that helps them to co-act. Interface-based Programming increases the modularity of the application and hence its maintainability at a later development cycles, especially when each module must be developed by different teams.

It is a well-known methodology that has been around for a long time and it is a core technology behind frameworks such as CORBA. This is particularly convenient when third parties develop additional components for the established system. They just have to develop components that satisfy the interface specified by the parent application vendor. Thus the publisher of the interfaces assures that he will not change the interface and the subscriber agrees to implement the interface as whole without any deviation.

An interface is therefore said to be a Contractual agreement and the programming paradigm based on this is termed as 'interface based programming'. Chain of Responsibility pattern has the intent to avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chains the receiving objects and passes the requests along the chain until an object handles it.

Command pattern is an Object behavioral pattern that decouples sender and receiver by encapsulating a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undo-able operations.

It can also be thought as an object oriented equivalent of call back method. Call Back:It is a function that is registered to be called at later point of time based on user actions. Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.

The 'iterator' design pattern is used liberally within the STL for traversal of various containers. The full understanding of this will liberate a developer to create highly reusable and easily understandable [ citation needed ] data containers.

The basic idea of the iterator is that it permits the traversal of a container like a pointer moving across an array. However, to get to the next element of a container, you need not know anything about how the container is constructed. This is the iterators job. By simply using the member functions provided by the iterator, you can move, in the intended order of the container, from the first element to the last element. The Builder Creational Pattern is used to separate the construction of a complex object from its representation so that the same construction process can create different objects representations.

Definition : A utility class that creates an instance of a class from a family of derived classes. Definition : A utility class that creates an instance of several families of classes. It can also returna factory for a certain group. The Factory Design Pattern is useful in a situation that requires the creation of many different types of objects, all derived from a common base type.

The Factory Method defines a method for creating the objects, which subclasses can then override to specify the derived type that will be created. Thus, at run time, the Factory Method can be passed a description of a desired object e.

The pattern works best when a well-designed interface is used for the base class, so there is no need to cast the returned object. In the following example, a factory method is used to create laptop or desktop computer objects at run time. Let's start by defining Computer , which is an abstract base class interface and its derived classes: Laptop and Desktop. The actual ComputerFactory class returns a Computer , given a real world description of the object.

Let's analyze the benefits of this design. First, there is a compilation benefit. If we move the interface Computer into a separate header file with the factory, we can then move the implementation of the NewComputer function into a separate implementation file. Now the implementation file for NewComputer is the only one that requires knowledge of the derived classes. Thus, if a change is made to any derived class of Computer , or a new Computer subtype is added, the implementation file for NewComputer is the only file that needs to be recompiled.

Everyone who uses the factory will only care about the interface, which should remain consistent throughout the life of the application. Also, if there is a need to add a class, and the user is requesting objects through a user interface, no code calling the factory may be required to change to support the additional computer type.

The code using the factory would simply pass on the new string to the factory, and allow the factory to handle the new types entirely.

Imagine programming a video game, where you would like to add new types of enemies in the future, each of which has different AI functions and can update differently. By using a factory method, the controller of the program can call to the factory to create the enemies, without any dependency or knowledge of the actual types of enemies.

Now, future developers can create new enemies, with new AI controls and new drawing member functions, add it to the factory, and create a level which calls the factory, asking for the enemies by name. Combine this method with an XML description of levels, and developers could create new levels without having to recompile their program. All this, thanks to the separation of creation of objects from the usage of objects. A prototype pattern is used in software development when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects.

This pattern is used, for example, when the inherent cost of creating a new object in the standard way e. Implementation : Declare an abstract base class that specifies a pure virtual clone method. Any class that needs a 'polymorphic constructor' capability derives itself from the abstract base class, and implements the clone operation.

Here the client code first invokes the factory method. This factory method, depending on the parameter, finds out the concrete class. On this concrete class, the clone method is called and the object is returned by the factory method. To implement the pattern, declare an abstract base class that specifies a pure virtual clone member function. The client, instead of writing code that invokes the new operator on a hard-wired class name, calls the clone member function on the prototype, calls a factory member function with a parameter designating the particular concrete derived class desired, or invokes the clone member function through some mechanism provided by another design pattern.

The function below demonstrates this concept:. The Singleton pattern ensures that a class has only one instance and provides a global point of access to that instance. It is named after the singleton set, which is defined to be a set containing one element.

This is useful when exactly one object is needed to coordinate actions across the system. Like a global variable, the Singleton exists outside of the scope of any functions. Traditional implementation uses a static member function of the Singleton class, which will create a single instance of the Singleton class on the first call, and forever return that instance.

One common use of the singleton design pattern is for application configurations. Configurations may need to be accessible globally, and future expansions to the application configurations may be needed. The subset C's closest alternative would be to create a single global struct. This had the lack of clarity as to where this object was instantiated, as well as not guaranteeing the existence of the object. Take, for example, the situation of another developer using your singleton inside the constructor of their object.

Then, yet another developer decides to create an instance of the second class in the global scope. If you had simply used a global variable, the order of linking would then matter. Since your global will be accessed, possibly before main begins executing, there is no definition as to whether the global is initialized, or the constructor of the second class is called first. This behavior can then change with slight modifications to other areas of code, which would change order of global code execution.

Such an error can be very hard to debug. But, with use of the singleton, the first time the object is accessed, the object will also be created. You now have an object which will always exist, in relation to being used, and will never exist if never used. A second common use of this class is in updating old code to work in a new architecture. Since developers may have used globals liberally, moving them into a single class and making it a singleton, can be an intermediary step to bring the program inline to stronger object oriented structure.

Note: In the above example, the first call to Singleton::GetInstance will initialize the singleton instance. This example is for illustrative purposes only; for anything but a trivial example program, this code contains errors.

Convert the interface of a class into another interface that clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces. The Bridge Pattern is used to separate out the interface from its implementation. Doing this gives the flexibility so that both can vary independently. Composite lets clients treat individual objects and compositions of objects uniformly. The Compositor itself is an abstract class, allowing for derivative classes to use different formatting algorithms such as double-spacing, wider margins, etc.

The Strategy Pattern is used to accomplish this goal. A Strategy is a method of encapsulating multiple algorithms to be used based on a changing context.

In this case, formatting should be different, depending on whether text, graphics, simple elements, etc. The use of a transparent enclosure allows elements that augment the behaviour of composition to be added to a composition.

These elements, such as Border and Scroller, are special subclasses of the singular element itself. This allows the composition to be augmented, effectively adding state-like elements.

Since these augmentations are part of the structure, their appropriate Operation will be called when the structure's Operation is called. This means that the client does not need any special knowledge or interface with the structure in order to use the embellishments.

This is a Decorator pattern, one that adds responsibilities to an object without modifying the object itself. Look-and-feel refers to platform-specific UI standards. These standards 'define guidelines for how applications appear and react to the user' pp. Since object creation of different concrete objects cannot be done at runtime, the object creation process must be abstracted.

This is done with an abstract guiFactory, which takes on the responsibility of creating UI elements. The abstract guiFactory has concrete implementations, such as MotifFactory, which creates concrete elements of the appropriate type MotifScrollBar. In this way, the program need only ask for a ScrollBar and, at run-time, it will be given the correct concrete element. This is an Abstract Factory. A regular factory creates concrete objects of one type. An abstract factory creates concrete objects of varying types, depending on the concrete implementation of the factory itself.

Its ability to focus on not just concrete objects, but entire families of concrete objects 'distinguishes it from other creational patterns, which involve only one kind of product object' pp. Just as look-and-feel is different across platforms, so is the method of handling windows.

Each platform displays, lays out, handles input to and output from, and layers windows differently. It is possible to develop 'our own abstract and concrete product classes', because 'all window systems do generally the same thing' p.

An abstract base Window class can be derived to the different types of existing windows, such as application, iconified, dialog. These classes will contain operations that are associated with windows, such as reshaping, graphically refreshing, etc. Each window contains elements, whose Draw functions are called upon by the Window 's own draw-related functions.

In order to avoid having to create platform-specific Window subclasses for every possible platform, an interface will be used. The Window class will implement a Window implementation WindowImp abstract class. This class will then in turn be derived into multiple platform-specific implementations, each with platform-specific operations. Hence, only one set of Window classes are needed for each type of Window , and only one set of WindowImp classes are needed for each platform rather than the Cartesian product of all available types and platforms.

In addition, adding a new window type does not require any modification of platform implementation, or vice versa. This is a Bridge pattern. Window and WindowImp are different, but related. Window deals with windowing in the program, and WindowImp deals with windowing on a platform. One of them can change without ever having to modify the other. The Bridge pattern allows these two 'separate class hierarchies to work together even as they evolve independently' p.

All actions the user can take with the document, ranging from entering text, changing formatting, quitting, saving, etc. Each menu item, rather than being instantiated with a list of parameters, is instead done with a Command object.

Command is an abstract object that only has a single abstract Execute method. Derivative objects extend the Execute method appropriately i. Execute would utilize the content's clipboard buffer.

These objects can be used by widgets or buttons just as easily as they can be used by menu items. To support undo and redo, Command is also given Unexecute and Reversible. In derivative classes, the former contains code that will undo that command, and the latter returns a boolean value that defines if the command is undoable.

Reversible allows some commands to be non-undoable, such as a Save command. All executed Commands are kept in a list with a method of keeping a 'present' marker directly after the most recently executed command. A request to undo will call the Command. Unexecute directly before 'present', then move 'present' back one command. Conversely, a Redo request will call Command. Execute after 'present', and move 'present' forward one. This Command approach is an implementation of the Command pattern.

It encapsulates requests in objects, and uses a common interface to access those requests. Thus, the client can handle different requests, and commands can be scattered throughout the application. This is the document editor's ability to textually analyze the contents of a document. Although there are many analyses that can be performed, spell check and hyphenation-formatting are the focus.

Removing the integer-based index from the basic element allows for a different iteration interface to be implemented. This will require extra methods for traversal and object retrieval. These methods are put into an abstract Iterator interface. Each element then implements a derivation of the Iterator , depending on how that element keeps its list ArrayIterator , LinkListIterator , etc.

Functions for traversal and retrieval are put into the abstract Iterator interface. Future Iterators can be derived based on the type of list they will be iterating through, such as Arrays or Linked Lists. Thus, no matter what type of indexing method any implementation of the element uses, it will have the appropriate Iterator.

This is an implementation of the Iterator pattern. It allows the client to traverse through any object collection, without needing to access the contents of the collection directly, or be concerned about the type of list the collection's structure uses. Now that traversal has been handled, it is possible to analyze the elements of a structure. It is not feasible to build each type of analysis into the element structure themselves; every element would need to be coded, and much of the code would be the same for similar elements.

Instead, a generic CheckMe method is built into the element's abstract class.



0コメント

  • 1000 / 1000