第二十四章 策略模式

83 阅读1分钟

策略模式定义

定义:

定义一系列算法,将每个算法封装起来,并让他们可以相互替换。策略模式可以让算法独立于使用它的客户而变化。

策略模式的结构

image.png

策略模式简单应用

实现一个买票的需求:

  • 学生八折优惠
  • 儿童五折优惠

代码如下

MovieTicket 电影票类

package designpatterns.strategy.myself;


/**
 * 电影票实体类
 */
public class MovieTicket {
    private double price;

    private  Discount discount;

    public Discount getDiscount() {
        return discount;
    }

    public void setDiscount(Discount discount) {
        this.discount = discount;
    }

    public double getPrice() {
        return discount.calculate(price);
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

Discount 打折接口

package designpatterns.strategy.myself;

/**
 * 打折接口
 */
public interface Discount {

    public double calculate(double price);
}

studentDiscount 类

package designpatterns.strategy.myself;

public class StudentDiscount implements Discount {

    private final double DISCOUNT = 0.8;

    @Override
    public double calculate(double price) {
        return price * DISCOUNT;
    }
}

ChildDiscount 类

package designpatterns.strategy.myself;

public class ChildDiscount implements Discount {

    private final double DISCOUNT = 0.5;
    @Override
    public double calculate(double price) {
        return price * DISCOUNT;
    }
}

config.xml

<?xml version="1.0"?>
<config>
   <className>designpatterns.strategy.myself.StudentDiscount</className>
</config>

XMLutil解析

//designpatterns.strategy.XMLUtil.java
package designpatterns.strategy.myself;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;

public class XMLUtil {
   //该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
   public static Object getBean() {
      try {
         //创建DOM文档对象
         DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder builder = dFactory.newDocumentBuilder();
         Document doc;                    
         doc =builder.parse(new File("src//designpatterns//strategy//myself//config.xml"));
      
         //获取包含类名的文本节点
         NodeList nl = doc.getElementsByTagName("className");
         Node classNode=nl.item(0).getFirstChild();
         String cName=classNode.getNodeValue();
        
         //通过类名生成实例对象并将其返回
         Class c=Class.forName(cName);
         Object obj=c.newInstance();
         return obj;
      }   
      catch(Exception e) {
         e.printStackTrace();
         return null;
      }
   }
}

client测试类

package designpatterns.strategy.myself;

public class Client {
    public static void main(String[] args) {
        MovieTicket movieTicket = new MovieTicket();
        double originalPrice = 60.0;
        movieTicket.setPrice(originalPrice);

        System.out.println("票原价:" +originalPrice);

        Discount bean = (Discount)XMLUtil.getBean();
        movieTicket.setDiscount(bean);

        System.out.println("票打折后价:" +movieTicket.getPrice());

    }
}

策略模式优缺点及适用环境

  • 优点

对算法进行自由切换和扩展,对多种条件选择语句可以替换。

  • 缺点

客户端必须知道所有的策略类,自行决定选择哪个策略类。 无法同时在客户端使用多个策略类