Apply Design Patterns In Java (Part 2)

Apply Design Patterns In Java (Part 2)

1. Overview

Previously, we explored the Strategy and Factory Method design patterns (Link), which enhance flexibility and reusability in our code. Now, we focus on the Decorator, Composite, and CoR patterns. These patterns dynamically add functionality to objects, structure complex hierarchies, and pass requests along a chain of handlers, respectively. Each pattern adheres to the Open/Closed Principle, promoting modular and maintainable software architectures. This article delves into their practical applications and benefits, showcasing how they can be used to create robust and scalable systems.

2. Decorator

2.1 Definition

Decorator is a structural design pattern that lets you attach new behaviors to objects by placing these objects inside special wrapper objects that contain the?behaviors.

2.2 Problem

We define multiple notifier classes (e.g., SMS, Email) and combine them to create composite notifiers.

Problem

Drawback of this design:

  1. Scalability Issues: As the number of notifier types grows, the combinations of notifiers increase exponentially, leading to a maintenance nightmare.
  2. Code Duplication: Each combination requires a new class, resulting in duplicated code and increased complexity.
  3. Lack of Flexibility: Adding new notifiers or modifying existing combinations requires changes to multiple parts of the codebase.

2.3 Solution

Using the Decorator pattern, we can dynamically add responsibilities to objects.

Solution

Benefits of this design:

  1. Flexibility: Easily extend the notification system with new notifiers without altering existing code.
  2. Reusability: Combine notifiers dynamically, reducing the need for multiple combinations of classes.
  3. Maintainability: Cleaner and more maintainable codebase with clear separation of concerns.
  4. Scalability: As new notifier types are added, they can be seamlessly integrated without exponential growth in class combinations.

2.4 Code Example

  • Problem

Problem

  • Solution

Solution

3. Composite

3.1 Definition

Composite is a structural design pattern that lets you compose objects into tree structures and then work with these structures as if they were individual?objects.

3.2 Problem

Consider a scenario where we have an Item class representing products, and each item can contain other items, forming a nested structure

Problem

Drawbacks of this design:

  1. Scalability Issues: Every item must have children, even if they are null or empty.
  2. Lack of Flexibility: The code becomes cumbersome and less intuitive when dealing with items that should not have children.
  3. Maintenance Challenges: Adding new types of items or changing the structure requires significant changes.

3.3 Solution

Using the Composite pattern, we can separate simple items from composite items, improving flexibility and scalability.

Solution

Benefits of this design:

  1. Flexibility: Easily add new item types without modifying existing code.
  2. Scalability: Manage complex hierarchies of items with simple code.
  3. Maintainability: Cleaner, more intuitive code structure that clearly separates simple items from composite items.

4. CoR Pattern

4.1 Definition

Chain of Responsibility is a behavioral design pattern that lets you pass requests along a chain of handlers. Upon receiving a request, each handler decides either to process the request or to pass it to the next handler in the?chain.

4.2 Problem

Consider a scenario where we have a simple web crawler. The WebCrawler class performs multiple steps: checking the URL, fetching content, extracting information, and saving data to a database. The original implementation might look like this

Problem

Drawbacks of this design

  1. Scalability Issues: Adding new steps or modifying existing ones requires changes to the crawl() method, making it difficult to maintain.
  2. Tight Coupling: Each step is tightly coupled within the crawl() method, reducing flexibility and reusability.
  3. Lack of Extensibility: The approach makes it challenging to extend or change the crawling process without modifying the core logic.

4.3 Solution

Using the Chain of Responsibility pattern, we can refactor the web crawler to improve flexibility and scalability. Each step in the crawling process will be handled by a separate handler.

Solution

Benefits of this design:

  1. Flexibility: Easily add, remove, or modify handlers without changing the core logic of the crawl() method.
  2. Scalability: New steps can be added to the chain as new handlers without impacting existing code.
  3. Loose Coupling: Each handler is independent, making the code more modular and easier to maintain.
  4. Extensibility: Handlers can be reused and extended, providing a flexible way to manage complex request processing flows.



D??ng Xuan ?à

??Java Software Engineer | Oracle Certified Professional

8 个月

Good to know

回复

Xin bí kíp ch?p màn hình x?n nh? trên v?i anh ?i ^^!

回复

要查看或添加评论,请登录

Nguyen Hai Dang (Eric)的更多文章

社区洞察

其他会员也浏览了