策略模式定义
定义:
定义一系列算法,将每个算法封装起来,并让他们可以相互替换。策略模式可以让算法独立于使用它的客户而变化。
策略模式的结构
策略模式简单应用
实现一个买票的需求:
- 学生八折优惠
- 儿童五折优惠
代码如下
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());
}
}
策略模式优缺点及适用环境
- 优点
对算法进行自由切换和扩展,对多种条件选择语句可以替换。
- 缺点
客户端必须知道所有的策略类,自行决定选择哪个策略类。 无法同时在客户端使用多个策略类