为什么要用设计模式系列之策略模式

策略模式在大多数情况下,用来优化大量的if-else或者switch代码,使代码逻辑更清晰。

if-else独霸江湖时代

请先看这样一个场景:

模拟一个人类,这个人类会产生不同的人类对象,因此每个人类对象也会对应不同的身份,A、B、C,甚至更多。但他们都要一个共同的行为,就是say方法。 现在我们判断,每个人类的身份,然后调用不同身份该say的内容。 在没有策略模式之前,大量的使用if-else来判断身份。

请再看​这样一段代码:

Main.java

public class Main {
    public static void main(String[] args) {
        Person person = new Person();
        person.identity = Identity.B;
        person.msg = "hello";

        if (person.identity == Identity.A) {
            new A().say(person.msg);
        } else if (person.identity == Identity.B) {
            new B().say(person.msg);
        } else if (person.identity == Identity.C) {
            new C().say(person.msg);
        }
    }
}

Person.java

public class Person {
    public Identity identity;
    public String msg;
}

A.java

public class A {
    public void say(String msg) {
        System.out.println("A say " + msg);
    }
}

B.java

public class B {
    public void say(String msg) {
        System.out.println("B say " + msg);
    }
}

C.java

public class C {
    public void say(String msg) {
        System.out.println("C say " + msg);
    }
}

Identity.java

public enum Identity {
    A,
    B,
    C
}

策略模式上位时代

怎么用策略模式来优化上面的代码呢?

应该这样来写,先抽象出一个不同身份人员的接口,抽象出具有相同的行为。

IdentityStrategy.java

public interface IdentityStrategy {
    void say(String msg);
}

然后A、B、C不同身份的class来分别实现这个接口。

A.java

public class A implements IdentityStrategy {
    public void say(String msg) {
        System.out.println("A say " + msg);
    }
}

B.java

public class B implements IdentityStrategy  {
    public void say(String msg) {
        System.out.println("B say " + msg);
    }
}

C.java

public class C implements IdentityStrategy  {
    public void say(String msg) {
        System.out.println("C say " + msg);
    }
}

按照上面接口的定义和具体类的实现,策略相当于定义好了,现在再编写一个策略工厂类,可以按不同的身份生产不同的对象。

StrategyFactory.java

import java.util.HashMap;
import java.util.Map;

public class StrategyFactory {
    private static Map<Identity, IdentityStrategy> map = new HashMap<Identity, IdentityStrategy>();

    static {
        map.put(Identity.A, new A());
        map.put(Identity.B, new B());
        map.put(Identity.C, new C());
    }

    private StrategyFactory() {}

    public static IdentityStrategy creator(Identity identity) {
        return map.get(identity);
    }
}

可以看到,其实就是定义个map将一个个具体的对象按不同的身份装起来了,再提个一个creator方法,传输不同的身份,就返回不同的实现类。

使用方式如下,将之前的Main.java修改成下面这样。

Main.java

public class Main {
    public static void main(String[] args) {
        Person person = new Person();
        person.identity = Identity.B;
        person.msg = "hello";

        IdentityStrategy strategy = StrategyFactory.creator(person.identity);
        strategy.say(person.msg);
    }
}

这样修改后的代码是不是更清晰了,当你有成千上百个身份的时候,不用写成千上百的if-else了。

本博客采用 知识共享署名-禁止演绎 4.0 国际许可协议 进行许可

本文标题:为什么要用设计模式系列之策略模式

本文地址:https://jizhong.plus/post/2020/03/strategy.html