Design Pattern

 

DESIGN PATTERN

       

 INTRODUCTION:

 

In Object-Oriented Modeling and Design (OOMD), design patterns are recurring solutions to common problems that arise during the design phase of software development. Design patterns provide a set of best practices and reusable templates that help designers and developers create more maintainable, flexible, and efficient software systems. These patterns have been refined over time and are based on the experiences of software engineers in solving specific types of problems.

 

HISTORY:

 

The history of design patterns in Object-Oriented Modeling and Design (OOMD) is closely tied to the development of object-oriented programming (OOP) itself. Design patterns as we know them today were popularized by the book "Design Patterns: Elements of Reusable Object-Oriented Software," often referred to as the "Gang of Four" (GoF) book, published in 1994.

C. Alexander (1936­), computer scientist  Critical of traditional modern architecture, patterns as solution guides in architecture, incremental building, interaction with users, empower laypeople to create designs Medieval cities built according to rules, not rigid masterplan.

 

WHY WE USE DESIGN PATTERN:

 

Design patterns are used in software development for several important reasons:

1.    Reusability: Design patterns provide proven and tested solutions to common software design problems. By using these patterns, developers can leverage existing best practices and avoid reinventing the wheel. This leads to more efficient development and reduces the chances of introducing errors.

2.    Maintainability: Design patterns promote modular and organized code. This modularization makes it easier to understand, modify, and maintain software systems over time. Changes to one part of the system are less likely to ripple through the entire codebase when design patterns are used appropriately.

3.    Scalability: Design patterns help create flexible and extensible software architectures. This means that as requirements change or the system needs to grow, it's easier to add new features or adapt to new circumstances without major architectural changes. This scalability is particularly important for long-term software projects.

4.    Communication: Design patterns provide a common vocabulary for developers and designers. When a team is familiar with design patterns, it's easier to discuss and communicate design decisions. This common understanding helps with collaboration and reduces misunderstandings.

5.    Best Practices: Design patterns embody best practices and proven solutions to specific types of problems. By following these patterns, developers are more likely to create software that is efficient, maintainable, and robust. It's a way to leverage the collective wisdom of the software development community.

 

TYPES OF DESIGN PATTERN:

 

1. Creational: These patterns are designed for class instantiation. They can be either class-creation patterns or object-creational patterns.

2. Structural: These patterns are designed with regard to a class's structure and composition. The main goal of most of these patterns is to increase the functionality of the class(es) involved, without changing much of its composition.

3. Behavioral: These patterns are designed depending on how one class communicates with others.

 


CREATIONAL DESIGN PATTERN:

 

Each creational pattern addresses specific needs in object creation. Creational design patterns are a subset of design patterns that deal with object creation mechanisms. They abstract the instantiation process, making it more flexible, efficient, and independent of the system's architecture. There are five commonly recognized creational design patterns:

  1. Singleton Pattern:
    • Intent: Ensure that a class has only one instance and provide a global point of access to that instance.
    • Use Cases: Logging systems, database connection pools, caching mechanisms.

 


 

 

 

  1. Factory Method Pattern:
    • Intent: Define an interface for creating an object, but let subclasses alter the type of objects that will be created.Use Cases: Frameworks for creating document types, UI components, or when you need to defer the decision of which class to instantiate to its subclasses.

 


 

 

  1. Abstract Factory Pattern:
    • Intent: Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
    • Use Cases: GUI libraries, cross-platform applications, or when you need to ensure that the created objects work together seamlessly.

 

 

 


 

 

 

 

  1. Builder Pattern:
    • Intent: Separate the construction of a complex object from its representation, allowing the same construction process to create different representations.
    • Use Cases: Building complex objects with many optional components, like HTML or XML document builders.

 

 


 

 

 

  1. Prototype Pattern:

Choosing the right pattern depends on the requirements of your application and the level of flexibility and control you need over object creation.




STRUCTURAL DESIGN PATTERN:

 

Structural design patterns in software engineering focus on simplifying the structure of a system by identifying relationships between objects and classes. These patterns help to compose objects and classes into larger structures, making them more flexible, efficient, and easier to maintain. Here are some commonly used structural design patterns:

  1. Adapter Pattern:
    • Intent: Allows objects with incompatible interfaces to work together. It wraps one class with an interface into another class that clients expect.
    • Use Cases: Integrating legacy systems, using third-party libraries, or making two incompatible classes collaborate.

 


 

  1. Bridge Pattern:
    • Intent: Separates an object's abstraction from its implementation, allowing both to vary independently.
    • Use Cases: Developing platform-independent graphical interfaces, managing various database systems, or creating different rendering engines for a shape in a drawing application.

 

 


 

 

 

 

 

  1. Composite Pattern:
    • Intent: Composes objects into tree structures to represent part-whole hierarchies. Clients can treat individual objects and compositions of objects uniformly.
    • Use Cases: Representing hierarchical structures like GUI components, organization structures, or file systems.

 

 


 

 

  1. Decorator Pattern:
    • Intent: Attaches additional responsibilities to objects dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
    • Use Cases: Adding features like borders, scrollbars, or formatting to text in a text editor, or enhancing the behavior of objects at runtime.
    • Use Cases: Adding features like formatting, encryption, or logging to objects without altering their core functionality.

 


 

 

 

BEHAVIOURAL DESIGN PATTERN:

 

Behavioral design patterns in software engineering deal with the interactions, responsibilities, and communication between objects and classes. They help define how objects collaborate and distribute responsibilities within a system. Here are some commonly used behavioral design patterns:

 

 

1.    Observer Pattern:

·       Intent: Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

·       Use Cases: Event handling systems, implementing publish-subscribe mechanisms, and keeping multiple views of data in sync.

 

 

 


 

 

 

 

2.    Strategy Pattern:

·       Intent: Defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy allows the algorithm to vary independently from clients using it.

·       Use Cases: Implementing different sorting algorithms, selecting various file compression methods, or dynamically changing behavior in a game.

 


3.    Command Pattern:

·       Intent: Encapsulates a request as an object, thereby allowing parameterization of clients with queues, requests, and operations. It also provides support for undoable operations.

·       Use Cases: Implementing undo/redo functionality, remote control systems, or queuing requests.

 

 

 

 


 

 

4.    Chain of Responsibility Pattern:

·       Intent: Passes a request along a chain of handlers. Each handler decides either to process the request or to pass it to the next handler in the chain.

·       Use Cases: Implementing request processing pipelines, input validation, or hierarchical event handling systems.

 

 

 


 

 

5.    State Pattern:

·       Intent: Allows an object to alter its behavior when its internal state changes. The object will appear to change its class.

·       Use Cases: Implementing state machines, managing the behavior of a context based on its state, or handling complex conditional logic.

 

 

 


 

 

CREATIONAL PATTERN PROGRAM:

 

Creational design patterns are a category of design patterns in software engineering that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. Here, I'll provide an example of a common creational design pattern, the Singleton pattern, in Python.

The Singleton pattern ensures that a class has only one instance and provides a global point of access to that instance. Here's a simple implementation in Python:

class Singleton:

    _instance = None

 

    def __new__(cls):

        if cls._instance is None:

            cls._instance = super(Singleton, cls).__new__(cls)

            cls._instance.init_singleton()

        return cls._instance

  def init_singleton(self):

        # Initialization code goes here

        self.value = 0

 

# Example usage:

s1 = Singleton()

s1.value = 10

 

s2 = Singleton()

 

print(s1.value)  # Output: 10

print(s2.value)  # Output: 10 (s2 is the same instance as s1)

 

In this example, we create a Singleton class with a private class variable _instance that stores the single instance of the class. The __new__ method is overridden to ensure that only one instance is created. When you create instances of the Singleton class, they will all refer to the same instance.

 

STRUCTURAL DESIGN PATTERN PROGRAM:

 

Structural design patterns are another category of design patterns that deal with how objects are composed to form larger structures. One common structural design pattern is the "Adapter" pattern. It allows the interface of an existing class to be used as another interface. Here's an example of the Adapter pattern in Python:

 

# Adaptee (the class to be adapted)

class OldSystem:

    def legacy_operation(self):

        return "Legacy operation result"

 

# Target interface (the interface we want to use)

class NewSystem:

    def new_operation(self):

        pass

 

# Adapter (adapts OldSystem to NewSystem interface)

class Adapter(NewSystem):

    def __init__(self, old_system):

        self._old_system = old_system

 

    def new_operation(self):

        return f"Adapted: {self._old_system.legacy_operation()}"

 

# Client code

def client_code(new_system):

    result = new_system.new_operation()

    print(result)

 

# Using the Adapter to adapt the OldSystem

old_system = OldSystem()

adapter = Adapter(old_system)

 

# Now, the client code can work with the NewSystem interface via the Adapter

client_code(adapter)

 

In this example:

1.    OldSystem represents an existing class with a legacy operation.

2.    NewSystem is the target interface that we want to use.

3.    Adapter is the adapter class that adapts OldSystem to the NewSystem interface.

The client_code function demonstrates how the adapter is used to invoke the legacy operation of OldSystem through the NewSystem interface.

 

BEHAVIOURAL DESIGN PATTERN PROGRAM:

 

Behavioral design patterns are design patterns that deal with how objects interact and communicate with each other. One commonly used behavioral design pattern is the "Observer" pattern. The Observer pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents (observers) are notified and updated automatically. Here's an example of the Observer pattern in Python:

 

# Subject (the object being observed)

class Subject:

    def __init__(self):

        self._observers = []

 

    def attach(self, observer):

        self._observers.append(observer)

 

    def detach(self, observer):

        self._observers.remove(observer)

 

    def notify(self, message):

        for observer in self._observers:

            observer.update(message)

 

# Observer (the objects that observe the subject)

class Observer:

    def update(self, message):

        pass

 

# ConcreteSubject (a specific subject to be observed)

class ConcreteSubject(Subject):

    def do_something(self):

        # Some action that changes the state of the subject

        self.notify("Subject's state has changed.")

 

# ConcreteObserver (a specific observer that reacts to changes)

class ConcreteObserver(Observer):

    def update(self, message):

        print(f"Received message: {message}")

 

# Client code

subject = ConcreteSubject()

observer1 = ConcreteObserver()

observer2 = ConcreteObserver()

 

subject.attach(observer1)

subject.attach(observer2)

 

subject.do_something()  # Triggers notification to observers

 

In this example:

  • Subject is the object being observed, and it maintains a list of observers.
  • Observer is an abstract class/interface for objects that want to observe the subject.
  • ConcreteSubject is a specific subject that can change its state. It notifies its observers when its state changes.
  • ConcreteObserver is a specific observer that reacts to changes in the subject's state.

The client code demonstrates how the Observer pattern is used. When the ConcreteSubject performs an action that changes its state, it notifies all attached observers, and they react by updating themselves with the new information.

 

 

 

 

 

-by

             PRADEEP.D(21USC016)

 

 

         

Comments

Popular posts from this blog

Radio Waves

Semantic Technology

Dynamic Memory Management