Java设计模式:策略模式

先看一个虚拟业务场景,现在有俩种支付方式:微信和支付宝,价钱小于2000使用微信支付,大于2000使用支付宝支付。

第一次代码实现

微信支付操作类:

public class WeixinPay {
    public  void pay() {
        System.out.println("使用微信支付");
  }
}

支付宝支付操作类:

public class AliPay {
    public void pay() {
        System.out.println("使用支付宝支付");
  }
}

客户端测试类:

public class MainTest {
    static final int PRICE = 1000;   
    public static void main(String[] args) {
        if (PRICE > 0 && PRICE < 2000) {
            WeixinPay weixinPay = new WeixinPay();
            weixinPay.pay();
        } else {
            AliPay aliPay = new AliPay();
            aliPay.pay();
        }
    }
}

上面的代码可不可以进行一些优化呢,答案是肯定的

  • 微信支付和支付宝支付可以实现同一个支付接口,实现多态
  • 客户端调用支付接口的时候是不应该考虑具体规则的,比较好的是把支付规则隐藏起来,客户端传一个具体的价格就可以完成支付

第二次代码实现

定义支付接口:

public interface Pay {
    void pay(); }

微信支付操作类:

public class WeixinPay implements Pay {
    public  void pay() {
        System.out.println("使用微信支付");
  }
}

支付宝支付操作类:

public class AliPay implements Pay {
    public void pay() {
        System.out.println("使用支付宝支付");
  }
}

为了隐藏选择支付方式的规则,选择建立一个上下文环境PayContext

public class PayContext {
    private static Pay aliPay = new AliPay();
    private static Pay weixinPay = new WeixinPay();
    
    public static void pay(int price) {
        if (price > 0 && price < 2000) {
            weixinPay.pay();
        } else {
            aliPay.pay();
        }
    }
}

客户端测试类:

public class MainTest {
    public static void main(String[] args) {
        PayContext payContext = new PayContext();
        payContext.pay(1000);
        payContext.pay(2500);
  }
}

策略模式

策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。

特点:

  • 定义了一族算法(业务规则)
  • 封装了每个算法
  • 这族算法可以互相替代
Java设计模式:策略模式_第1张图片

结合上面的业务场景,对象具有的某个行为指的就是支付行为,但是根据不同的情况需要使用不同的支付方式,这个就相当于不同的算法实,行为相同实现不同,这正是接口的作用。个人认为策略模式真正的核心是策略这俩个字,就是什么时候选择什么样的算法实现,这个选择过程一般是在Context里实现,这个选择过程当然也可以放在客户端调用的时候,只是这样用起来很不方便,支付的时候直接调用一个方法更方便,更优雅,耦合度更低,代码分工更明确,如果修改支付规则,直接修改Context即可。

附上Wiki代码示例:

//StrategyExample test application

class StrategyExample {

    public static void main(String[] args) {

        Context context;

        // Three contexts following different strategies
        context = new Context(new FirstStrategy());
        context.execute();

        context = new Context(new SecondStrategy());
        context.execute();

        context = new Context(new ThirdStrategy());
        context.execute();

    }

}

// The classes that implement a concrete strategy should implement this

// The context class uses this to call the concrete strategy
interface Strategy {

    void execute();

}

// Implements the algorithm using the strategy interface
class FirstStrategy implements Strategy {

    public void execute() {
        System.out.println("Called FirstStrategy.execute()");
    }

}

class SecondStrategy implements Strategy {

    public void execute() {
        System.out.println("Called SecondStrategy.execute()");
    }

}

class ThirdStrategy implements Strategy {

    public void execute() {
        System.out.println("Called ThirdStrategy.execute()");
    }

}

// Configured with a ConcreteStrategy object and maintains a reference to a Strategy object
class Context {

    Strategy strategy;

    // Constructor
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void execute() {
        this.strategy.execute();
    }

}

你可能感兴趣的:(Java设计模式:策略模式)