Basics of Design Patterns - Overview (1/2)

Table of contents

1. Definition of design pattern

2. Three major categories of design patterns

3. Principles of design patterns

4. Main design pattern directory

4.1 Creational Patterns

4.2 Structural Patterns

4.3 Behavioral Patterns


1. Definition of design pattern

Design pattern (Design pattern) is a set of classified and cataloged summary of code design experience that is used repeatedly, known to most people. These patterns represent best practices that are typically adopted by experienced object-oriented software developers to solve common problems frequently encountered during the software design process.

Design patterns provide a common language and framework that allows developers to communicate complex system architectures more efficiently, and allows them to reuse existing solutions to avoid reinventing the wheel. Each design pattern describes a recurring problem in software development and the core ideas that solve it. They help improve code readability, maintainability, and reliability, and make software engineering more engineered and standardized.

2. Three major categories of design patterns

Design patterns are divided into three categories: creational patterns (focused on the creation of objects), structural patterns (focused on the combination of objects), and behavioral patterns (focused on the interaction and distribution of responsibilities between objects).

When you look at some information, you will find that someone specifically mentioned the J2EE class design pattern. This usually refers to a series of design patterns used in Java 2 Platform, Enterprise Edition (J2EE). These design patterns are proposed for the special needs of developing enterprise-level applications. They may not belong to the three major categories in the classic Gang of Four (GoF) design pattern classification: creational, structural and behavioral.

Therefore, it is reasonable to say that "J2EE design patterns" are a separate category or subset of design patterns. This is mainly because J2EE applications have their own unique architectural characteristics and challenges, such as dealing with multi-layer architecture, distributed computing, transaction management, security, etc. In order to solve these problems, developers have summarized a series of best practices specific to the J2EE environment. These practices are sometimes called "J2EE design patterns".

It should be noted that with the development of technology, especially the Java platform from J2EE to Java EE (Java Platform, Enterprise Edition), and now Jakarta EE (an enterprise-level Java specification maintained by the Eclipse Foundation), some early and J2EE-related patterns may change or no longer apply. At the same time, new models may emerge to accommodate new technologies and frameworks.

For example, everyone is familiar with the MVC design pattern, which is a pattern that beginners must understand. For example, the classic Struts framework is based on the MVC design pattern. The MVC (Model-View-Controller) pattern is a classic architectural pattern in software engineering. It has been widely adopted in the J2EE era and has had a profound impact on subsequent Web development frameworks and enterprise-level applications. However, with the development of technology, especially in the process from J2EE to Java EE to Jakarta EE, many new programming models and frameworks have emerged, which provide different ways to organize and manage the structure of applications.

While MVC is still a valid design principle, it may no longer map as directly to components in modern Java frameworks as it once did. For example, in the Spring framework, although the basic concept is similar to MVC, the implementation methods are different, such as processing requests through DispatcherServlet, using @Controller and @RequestMapping annotations to define controller behavior, etc.

In addition, other modern front-end frameworks, such as AngularJS, React or Vue.js, also adopt a similar model, but the specific implementation and division of labor are different from traditional MVC. These frameworks typically combine the responsibilities of the view and controller, while the model handles the data and business logic.

Therefore, it is not entirely accurate to say that the MVC pattern is no longer suitable for all situations. Its core idea, separation of concerns, remains an important principle in modern software design. However, over time, this idea may manifest itself in different forms or be combined with other patterns to form more complex architectures. Developers need to decide the most suitable architecture model based on specific project requirements and technology selection.

3. Principles of design patterns

Here are a few design principles commonly used in software engineering:

1. Single Responsibility Principle (SRP)
   - A class or module should have only one reason for change.
   - This principle emphasizes dividing the responsibilities of the code as clearly and independently as possible.

2. Open-Closed Principle (OCP)
   - Open for expansion, closed for modification.
   - This principle recommends achieving code scalability through abstraction and trying to avoid directly modifying existing code.

3. Liskov Substitution Principle (LSP)
   - A subtype must be able to replace its base type.
   - This principle requires that in the inheritance system, subclasses should be able to replace parent classes without restrictions without causing errors or exceptions.

4. Interface Segregation Principle (ISP)
   - Clients should not be forced to rely on methods they do not need.
   - This principle advocates creating smaller, more specialized interfaces rather than large, general-purpose interfaces.

5. Dependency Inversion Principle (DIP)
   - High-level modules should not depend on low-level modules, both should rely on abstractions.
   - Abstraction should not depend on details, details should depend on abstraction.
   - This principle helps improve the flexibility and maintainability of the code.

6. Composite Reuse Principle (CRP)
   - Try to use object combination instead of inheritance to achieve reuse.
   - This principle encourages the use of associations to achieve code reuse, thereby reducing coupling.

7. Law of Demeter (LoD) or the principle of least known
   - An object should know as little as possible about other objects.
   - This principle aims to reduce the coupling between modules and improve the readability and maintainability of the code.

8. Programming by Contract (PBC)
   - There should be a clear agreement (contract) between classes and methods, including preconditions, postconditions and unchanged conditions.
   - This principle can help ensure the correctness and reliability of the code.

9. Command-Query Separation (CQS)
   - A method can either change the state of the object (command) or return a result (query), but not both at the same time These two things.
   - This principle helps improve code predictability and testability.

The above principles are all designed to help developers write more robust, readable, maintainable and scalable code. In actual projects, these principles need to be applied flexibly according to specific scenarios and balanced with other design principles.

4. Main design pattern directory

4.1 Creational Patterns

Creational design patterns are used to deal with the creation process of objects. They decouple the instantiation and use of objects. The following are some of the main patterns among creational patterns:

1. Factory Method
   - Define an interface for creating objects and let subclasses decide which class to instantiate.
   - Causes the instantiation of a class to be delayed to its subclasses.

2. Abstract Factory
   - Provides an interface for creating a series of related or interdependent objects without specifying a specific class.
   - Suitable for situations where multiple related object series need to be provided.

3. Builder
   - Separates the construction of a complex object from its representation, so that the same construction process can create different representations.
   - Suitable for when the products that need to be generated have multiple expressions or assembly methods.

4. Prototype
   - Provides a method to copy new objects from existing objects instead of directly creating new objects through the new operator.
   - This mode is suitable when the system needs to create a large number of similar objects and the creation process is time-consuming.

5. Singleton
   - Ensure that a class has only one instance and provide a global access point.
   - Suitable for situations where only one instance is needed to coordinate certain activities of the system.

The main purpose of these patterns is to hide the details of object creation, making the code more flexible and extensible, and reducing the coupling between codes. In actual development, choosing the appropriate creation mode according to specific needs and scenarios can make the code more robust and easier to maintain.

4.2 Structural Patterns

Structural design patterns focus on the combination of objects and classes. They provide methods for organizing objects together to better implement system functions. The following are some of the major patterns in structural patterns:

1. Adapter
   - Converts the interface of a class into another interface that the customer wants.
   - Allows originally incompatible classes to work together.

2. Bridge
   - Separates the abstract part from its implementation part so that they can change independently.
   - Provides a way to decouple the abstract part and the implementation part.

3. Decorator
   - Dynamically adds some additional responsibilities to an object.
   - Provides a more flexible alternative to inheritance for extending the functionality of an object.

4. Facade
   - Provide a consistent interface for a set of interfaces in the subsystem.
   - It defines a high-level interface to make the subsystem easier to use.

5. Flyweight
   - Use sharing technology to effectively support a large number of fine-grained objects.
   - Reduces memory usage and improves program performance.

6. Proxy
   - Provides a proxy for other objects to control access to this object.
   - Can be used to create lightweight objects or lazy loading, permission checking and other scenarios.

These patterns improve the reusability, flexibility and scalability of code and reduce the complexity of the system by changing the combination relationship between objects. In actual development, choosing the appropriate structural pattern according to specific needs and scenarios can make the code more robust and easier to maintain.

4.3 Behavioral Patterns

Behavioral design patterns focus on communication and allocation of responsibilities between objects. They describe how to divide the responsibilities of an algorithm between classes or objects. Here are some of the major behavioral patterns:

1. Template Method
   - Defines the framework of an algorithm in an abstract class and defers some steps to subclasses.
   - It allows subclasses to redefine specific steps of the algorithm without changing the structure.

2. Command
   - Encapsulates a request as an object, allowing users to use different requests, queues or log requests, and also supports revocable operate.
   - Makes new request types easy to add by separating operations from receivers.

3. Strategy
   - Defines a series of algorithms and encapsulates each algorithm so that they can be replaced with each other.
   - The strategy pattern allows the algorithm to change independently of the customers using the algorithm.

4. Chain of Responsibility
   - Allows the request to be passed along the handler chain until it is processed.
   - Eliminate the coupling relationship between the request sender and receiver.

5. State
   - Allows an object to change its behavior when its internal state changes.
   - When the control flow is based on the state of the object, it is more appropriate to use the state pattern.

6. Observer
   - Defines a one-to-many dependency relationship. When the state of an object changes, all objects that depend on it will get Notifications and automatic updates.
   - Provides a one-to-many publish/subscribe mechanism between objects.

7. Visitor
   - Represents an operation that acts on each element in an element structure.
   - It allows you to define new operations on each element without modifying its class.

8. Memento
   - Capture the internal state of an object so that it can be restored later without breaking encapsulation.
   - Provides a method for state saving and rollback.

9. Mediator
   - Define a mediator object to encapsulate a series of object interactions.
   - Reduces the complexity and coupling of the system.

10. Iterator (Iterator)
    - Provides a way to sequentially access the elements of an aggregate object without exposing its underlying representation.
    - Supports traversing various data structures in a unified manner.

11. Interpreter
    - Given a language, define a representation of its grammar, and define an interpreter that uses that representation to interpret sentences in language.
    - This mode is suitable when you need to implement a small-scale language or expression parsing.

These patterns improve code reusability, flexibility and scalability, and simplify complex system design by rationally organizing interactions between objects. In actual development, choosing appropriate behavioral patterns based on specific needs and scenarios can make the code more robust and easier to maintain.

Let’s sort this out first. Later we will have time to learn several common design patterns in detail.

おすすめ

転載: blog.csdn.net/giszz/article/details/134772692