java设计模式之策略模式
文章目录
1.简介
为了应对需求的变更,我们需要采用一些设计模式来降低类之间的耦合度。
策略模式将可变的部分从程序中抽象分离成算法接口,在该接口下分别封装一系列算法实现。
2.适用场景
策略模式主要适用于以下场景:
① 相关的类仅仅是行为差异,例如要给鸭子类添加飞行功能(在鸭子类下继承了很多种类的鸭子,不同鸭子的飞行不一定相同)
② 在运行时选取不同的算法变体,例如支付功能,选择不同的银行进行支付。
③ 通过条件语句在多个分支中选取其一。
3.一个策略模式示例——打印机的例子
某公司专门销售各种打印机,销售打印机时都有一定的折扣让利给顾客,但折扣计算的方法有很多种,如:不打折;每台减扣固定的金额;按售价的5%打折等等,且折扣计算方法可能发生变化。
①声明策略接口Discount,声明打折方法discount
package strategy;
public interface Discount {
void discount();
}
②各种Discount的实现类,实现不同的打折方式
无折扣:
package strategy.disIpl;
import strategy.Discount;
public class noDiscount implements Discount {
public void discount(){
System.out.println("没有折扣!");
}
}
折扣5%:
package strategy.disIpl;
import strategy.Discount;
public class PercentDis implements Discount {
public void discount(){
System.out.println("折扣5%!");
}
}
③编写抽象类打印机类,方便不同种类打印机的继承
在抽象类中,声明一个Discount接口的实例,从而使它可以有打折这个行为。
package strategy;
import strategy.Discount;
public abstract class Printer {
private Discount dis;
public abstract void display();
public Printer(){
}
public void setDis(Discount discount){
dis = discount;
}
public void discount(){
dis.discount();
}
}
④编写具体类实现抽象类Printer并注入策略实现算法
Printer1:
package strategy;
import strategy.disIpl.*;
public class Printer1 extends Printer {
public Printer1(){
super();
super.setDis(new noDiscount());
}
public void display(){
System.out.println("这是一号打印机:");
}
}
Printer2:
package strategy;
import strategy.disIpl.*;
public class Printer2 extends Printer {
public Printer2(){
super();
super.setDis(new PercentDis());
}
public void display(){
System.out.println("这是二号打印机:");
}
}
⑤test
package strategy;
public class PrinterTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Printer1 printer1 = new Printer1();
printer1.display();
printer1.discount();
Printer2 printer2 = new Printer2();
printer2.display();
printer2.discount();
}
}
4.类图
当然这个类图里还比上面的代码多了一种折扣方式和一种打印机。
5.总结
从上面我们很容易看出来这个方法很易于修改,我们要再增加打印机或者更改折扣方式都是非常容易的。
其实上面打印机的例子里除了策略模式我们还有两种方式可以实现:
①直接在父类中实现其中一种打折方法,在子类中如果和父类不同则进行覆写。但是这样的话万一忘记覆写就会出错。
②在父类中添加一种打折的抽象方法,但不实现。←增加了子类的代码量,如果有很多很多很多打印机都用的同一种打折方法,就增加了很多不必要的代码。
策略模式相对好地解决了这个问题,但它也有缺点,那就是增加了对象的数量。