Github source address

An overview of 23 design patterns

  • Java Language Design – An overview of 23 design patterns

Creation pattern

  • Factory Method Pattern
  • Abstract Factory Pattern
  • Builder Mode
  • Prototype mode
  • Singleton

Structural mode

  • Facade Pattern
  • Adapter mode (Adapter)
  • Proxy mode
  • Composite mode
  • Flyweight Mode
  • Decorator pattern
  • Bridge mode (Bridge)

Behavioral pattern

  • Mediator Mode
  • Observer Model
  • Command mode
  • Iterator pattern (Iterator)
  • Template Method
  • Strategy Pattern
  • State mode
  • Memento Mode
  • Interpreter mode
  • Chain of Responsibility model
  • Visitor Pattern

define

Define a set of algorithms, encapsulate them one by one, and make them interchangeable.

The advantages and disadvantages

Advantages: 1. The algorithm can be switched freely. 2. Avoid using multiple conditional judgments. 3. Good expansibility.

Disadvantages: 1. Policy classes will increase. 2. All policy classes need to be exposed.

Usage Scenarios:

1. If there are many classes in a system that are distinguished only by their behavior, the use of the policy pattern dynamically allows an object to choose one behavior among many. A system needs to dynamically choose one of several algorithms. 3. If an object has many behaviors, these behaviors can be implemented using multiple conditional selection statements without appropriate patterns.

implementation

The policy pattern contains three roles:

Abstract Strategies: Typically implemented by interfaces or abstract classes. The common interface of several specific policies is defined, and different algorithms in the specific policy class implement this interface in different ways. Context uses these interfaces to call algorithms that are implemented differently. ConcreteStrategy: Implements the Strategy interface or inherits from the abstract Strategy class, encapsulating concrete algorithms and behaviors. Environment class (Contex) : Holds a reference to a common policy interface that is called directly to the client.

When we shop on e-commerce platforms, there are many payment methods to choose from, such as Alipay, wechat, UnionPay and so on.

Here we can think about how the e-commerce platform judges and performs subsequent operations according to the payment method we choose when executing the operation of payment.

The most obvious thing to think about is doing a series of if and else operations in your code depending on the payment method the user chooses.

if (Objects.equals(paymentWay, "Alipay"Alipay payment processing logic... }else if (Objects.equals(paymentWay, "WeChat") {wechat payment processing logic... }else if (Objects.equals(paymentWay, Unionpay Flash paymentUnionpay cloud flash payment processing logic... }else if (Objects.equals(paymentWay, "xxx") {XXX payment processing logic... }Copy the code

Check the code above to see if it feels dizzy and stuffy. There is a lot of logic processing in each if else. If you add a payment method, you need to add an if else, which will not only make the code less readable, but also greatly increase the maintenance cost in the later period. And the probability of error is also relatively high.

So this is a good place to use the policy pattern for a wave of refactoring.

Policy pattern refactoring

We can abstract the payment operation as a policy interface.

// Payment method
public interface Payment {
    void payment(a);
}
Copy the code

Then define the concrete implementation of different payment methods.

Alipay payment:

public class AliPayPayment implements Payment {

    @Override
    public void payment(a) {
        System.out.println("Alipay Pay"); }}Copy the code

Wechat Pay:

public class WechatPayPayment implements Payment {

    @Override
    public void payment(a) {
        System.out.println("Wechat Pay"); }}Copy the code

Unionpay flash payment:

public class UnionPayPayment implements Payment {

    @Override
    public void payment(a) {
        System.out.println(Unionpay Flash payment); }}Copy the code

Redefine the container class for the policy pattern.

public class PaymentContext {

    private Payment payment;

    public PaymentContext(Payment payment) {
        this.payment = payment;
    }

    public void payment(a){ payment.payment(); }}Copy the code

With that defined, now when it comes to payments, we simply initialize the policy container and pass in the corresponding payment method implementation, and then call the Payment () method of the policy container, depending on the payment method.

class Test {
    public static void main(String[] args) {
        // Pay by Alipay
        PaymentContext aliPay = new PaymentContext(new AliPayPayment());
        aliPay.payment();
        // Wechat Pay
        PaymentContext wechatPay = new PaymentContext(new WechatPayPayment());
        wechatPay.payment();
        // UnionPay flash payment
        PaymentContext unionPay = new PaymentContext(newUnionPayPayment()); unionPay.payment(); }}Copy the code
Alipay pay wechat Pay UnionPay cloud flash paymentCopy the code