Detailed description of Java design patterns (4)

 1. Template method pattern

The Template Method pattern is a behavioral design pattern that defines the skeleton of an algorithm in operation, deferring different implementations of the algorithm to subclasses. This mode allows subclasses to redefine certain steps in the algorithm to meet different needs without changing the algorithm structure.

The template method pattern is a pattern designed by moving unchanged behavior to the super class and removing duplicate code in the subclass, so that the subclass can focus on changes in its own behavior rather than changes in the overall system.

In the template method pattern, the superclass usually defines a template method, which internally calls multiple other abstract methods. Subclasses need to implement these abstract methods to define their own behavior. This pattern can cope with changing needs during development very well, because it allows you to change the implementation of some behaviors without changing the algorithm structure.

Suppose we want to write a file reader that needs to read data from a file and convert the data into a specific format. This conversion process can be implemented by subclasses, while the process of reading files is fixed and can be implemented in the parent class. Here is a sample code:

// 抽象文件读取器
public abstract class FileReader {
    // 模板方法
    public final void read() {
        open();
        readData();
        close();
    }
    
    // 打开文件
    protected void open() {
        System.out.println("打开文件");
    }
    
    // 读取文件数据,由子类实现
    protected abstract void readData();
    
    // 关闭文件
    protected void close() {
        System.out.println("关闭文件");
    }
}
// 文本文件读取器
public class TextFileReader extends FileReader {    
@Override    
protected void readData() {        
System.out.println("读取文本文件数据");    
}
}
// 图片文件读取器
public class ImageFileReader extends FileReader {
    @Override
    protected void readData() {
        System.out.println("读取图片文件数据");
    }
}

// 测试程序
public class Test {
    public static void main(String[] args) {
        // 使用文本文件读取器
        FileReader reader = new TextFileReader();
        reader.read();
        
        // 使用图片文件读取器
        reader = new ImageFileReader();
        reader.read();
    }
}

Advantages and Disadvantages

Template Method Pattern is a behavioral design pattern that defines an algorithm skeleton in an operation and defers certain steps to subclasses. Template methods allow subclasses to redefine specific steps of an algorithm without changing the structure of the algorithm.

In the template method pattern, an abstract class defines a template method, which gives the skeleton of an algorithm and defers the specific implementation to subclasses. Abstract classes usually also define some basic operations, which can be used directly by subclasses or further extended and improved by subclasses.

The advantages of the template method pattern are:

it separates the framework of the algorithm from the specific implementation, making the implementation more flexible;
it can avoid duplication of code and reduce code redundancy;
it allows subclasses to redefine certain aspects of the algorithm without changing the algorithm structure. step.
The disadvantages of the template method pattern are:

since the algorithm framework is fixed, if the algorithm framework needs to be changed, the code of the abstract class needs to be modified, which may lead to some potential risks; since the implementation of the
algorithm is delayed to subclasses, Therefore, the number of subclasses may increase, increasing the complexity of the system.

Template mode vs strategy mode

When I chose template mode and strategy mode, I found that both could fully meet my needs. Then I checked a lot of information on the Internet, hoping to find two modes that could tell me which situation I need to choose when choosing technology. I am ashamed to say that I have not found this model until now, because the Internet only told me the difference between the two implementation postures, but did not explain how to select the specific model. Below I will list the most important parts of the information I collected. , give you some reference.

Someone please explain to me what is the difference between Template Method Pattern and Strategy Pattern?

As far as I can tell they are 99% identical - the only difference is that the template method pattern has an abstract class as a base class, while the strategy classes use an interface implemented by each concrete strategy class.

However, as far as customers are concerned, they spend exactly the same way – is this correct?

The main difference between the two lies in the choice of specific algorithms.

When using the Template method pattern, subclassing the template occurs at compile time. Each subclass provides a different concrete algorithm by implementing the abstract methods of the template. When a client calls a method of a template's external interface, the template calls its abstract methods (its internal interface) as needed to invoke the algorithm.

In contrast, the Strategy pattern allows algorithms to be selected at runtime through containment. Concrete algorithms are implemented through separate classes or functions that are passed as parameters to the constructor or constructor method. Which algorithm is selected for this parameter will change based on the state of the program or input dynamically.

In summary:

  • Template method pattern: compile-time algorithm selection via subclassing

  • Strategy Pattern: Runtime algorithm selection via containment

The above is a complete excerpt of the difference description on the Internet. I only see the difference in implementation postures. However, if this can guide me to choose a model, I think it is not enough. The following may be more specific:

resemblance:

  • Both strategy and template method patterns can be used to satisfy the open-closed principle, making software modules easy to extend without changing the code.

  • Both patterns represent the separation of general functionality from the detailed implementation of that functionality. However, there are some differences in the granularity they provide.

difference:

  • In the strategy, the coupling between the client and the strategy is looser, while in the template approach, the two modules are more tightly coupled.

  • In the strategy, although abstract classes can also be used according to specific situations, an interface is mostly used instead of a concrete class. In the Template method, abstract classes or concrete classes are mostly used instead of interfaces.

  • In Strategy mode, the overall behavior of a class is generally represented by an interface. On the other hand, the Template method is used to reduce code duplication, and the boilerplate code is defined in the basic framework or abstract class. In Template Method, you can even have a concrete class with a default implementation.

  • In short, you can change the entire strategy (algorithm) in Strategy pattern, but in Template pattern, only some things change (part of the algorithm) while the rest of the events remain the same. In Template Method, the invariant step is implemented in an abstract base class, while the variant step is either the default implementation or not implemented at all. In the Template method, the component designer enforces the steps and ordering of steps required by the algorithm, but allows the component client to extend or replace certain steps.

After seeing the above summary, I still feel that my questions have not been answered. Finally, I will quote an explanation of the difference online:

Template mode:

  • It is based on inheritance.

  • Defines the skeleton of the algorithm that cannot be changed by subclasses. Only certain operations can be overridden in subclasses.

  • The parent class fully controls the algorithm and only distinguishes specific steps from specific classes.

  • Binding is done at compile time.

Strategy mode:

  • It is based on authorization/composition.

  • It changes the content of the object by modifying the behavior of the method.

  • It is used to switch between algorithm families.

  • It changes the behavior of an object at runtime by completely replacing one algorithm with another algorithm at runtime.

  • Binding is done at runtime.

As someone with obsessive-compulsive disorder, I haven't found the root of the problem and always feel like something is wrong. Let me share my understanding of the difference between the two. To be honest, I have seen differences in the implementation postures between the two design patterns. As for the strategy pattern that requires defining a unified interface, the template pattern does not do this, etc., I don’t agree with it, because I sometimes give The template pattern defines a common interface. Then some people say that the strategy pattern needs to define a bunch of objects, but the template pattern does not. If there are 10 different penguins, doesn’t the template pattern also need to define 10 different penguin classes, and then implement them specifically for specific methods? ?

Therefore, I feel that these two design modes have not been divided into either/or. I just use them as I like, such as "eat, sleep, and play beans" in penguin mode. I don't need a fixed execution process. For example, if I only need to play Doudou and only need to make a specific abstraction of a method, I am willing to choose the strategy mode, because I feel that this will make the objects I need to use clearer. If I have a fixed execution process, such as "eating, sleeping, playing Doudou", I would prefer to use the template method. Maybe I have read too much code and am used to it, so I prefer to use the template method to standardize the fixed execution process of the code. .

Of course, I can also combine the two. For example, we can use the template method to implement these three penguins. But for the middlePenguin, there may be Penguin Boy A, Penguin Boy B, and Penguin Boy C. They all like next door. Penguin sister, but they like her in different ways. Some have a crush, some express their love directly, and some are domineering. I can use the strategy mode to specify how they express their feelings towards the Penguin sister.

life examples

The application of template method pattern is relatively common in life. For example, we want to make a dish of fish-flavored shredded pork. Generally speaking, making fish-flavored shredded pork requires the following steps: preparing ingredients, chopping vegetables, seasoning, stir-frying, and taking out of the pot. The order of these steps cannot be changed, otherwise you will not be able to make an authentic fish-flavored shredded pork.

Then we can abstract these steps and define a template class that contains the execution order of these steps. Each specific fish-flavored shredded pork chef can inherit this template class and implement its own specific method. For example, some chefs like to add a little onion, ginger, and garlic, some chefs like to add some chili, and some chefs will use starch to coat the meat slices evenly before frying. These implementation details are completed in the subclass, and the template method pattern ensures that the execution order of the steps remains unchanged.

The advantage of this is that when we want to change the method of fish-flavored shredded pork, we only need to modify the corresponding subclass. For example, if we want to make fish-flavored shredded pork sweet, we can create a new subclass that inherits the template class and reimplement the seasoning steps. The template method pattern makes the code more extensible and makes it easier for us to modify the code without affecting other parts.

2.Adapter mode

The adapter pattern is a structural design pattern whose main function is to enable originally incompatible interfaces to cooperate with each other.

Code example for adapter pattern:

target interface, source interface

public interface Target {
    void request();
}
public class Adaptee {    
void specificRequest() {        
System.out.println("执行源接口的方法");   
}
}

adapter

public class Adapter implements Target {

    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        adaptee.specificRequest();
    }
}

use

public class Client {
    public static void main(String[] args) {
        Adaptee adaptee = new Adaptee();
        Target target = new Adapter(adaptee);
        target.request();
    }
}

If Adaptee is a 3.5mm headphone jack, Target is a Type-C headphone, and Adapter is an adapter that converts the 3.5mm headphone jack into a Type-C jack.

describe

In the above code, the Target interface is the target interface that the adapter wishes to implement. The Adaptee class is an existing source interface, but its methods are incompatible with the Target interface. The Adapter class implements the Target interface and uses the Adaptee class internally to implement the request() method. By using the Adapter class, client code can call the request() method without directly calling the specificRequest() method.

scenes to be used

1. The interface of the existing class does not match the requirements. For example, you can use adapter mode to provide compatibility with older printers without changing client code.

2. Use third-party components in some classes. The interfaces of these components may not meet system design standards, or they may not provide necessary functions. The adapter pattern can convert the interfaces of these components into the interfaces expected by the system to meet the needs of the system.

3. You need to use multiple existing subclasses, but these subclasses lack some common functions. In this case, the adapter pattern can add these missing functions without modifying the existing code.

4. A unified output format is needed to output multiple classes of data. At this time, you can use the adapter pattern to convert the interfaces of multiple classes into a unified output format.

Advantages and Disadvantages

Class Adapter
Advantages: The methods of the Adaptee class can be rewritten according to needs, which enhances the flexibility of the Adapter.
Disadvantages: There are certain limitations. Because the class adapter needs to inherit the Target class, and Java has a single inheritance mechanism, the Adaptee class must be an interface.

Advantages of object adapter
: The same Adapter can adapt both the Adaptee class and its subclasses to the target interface.
Disadvantages: When you need to redefine the behavior of Adaptee, you need to redefine the subclass of Adaptee and match the adapter combination.

Advantages of interface adapter
: It can selectively rewrite interface methods flexibly and conveniently.
Disadvantages: Because it is in the form of an anonymous inner class, it is not conducive to code reuse.

Guess you like

Origin blog.csdn.net/qq_18235445/article/details/129315666