设计模式
- 策略模式
-
基本介绍
- 策略模式中,定义算法族(策略组)分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
- 这算法体现了几个设计原则,第一:把变化的代码从不变的代码中分离出来;第二:针对接口编程而不是具体类(定义了策略接口);第三:多用组合/聚合,少用继承(客户)通过组合方式使用策略。
-
代码
public abstract class Duck { protected FlyBehavior flyBehavior; public abstract void display(); public void quack() { System.out.println("鸭子嘎嘎叫"); } public void swim() { System.out.println("鸭子游泳"); } public void fly() { if(flyBehavior!=null) { flyBehavior.fly(); } } public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } } public class PekingDuck extends Duck{ public PekingDuck() { flyBehavior=new NoFlyBehavior(); } @Override public void display() { System.out.println("北京鸭"); } } public class ToyDuck extends Duck{ public ToyDuck() { flyBehavior=new NoFlyBehavior(); } @Override public void display() { System.out.println("玩具鸭"); } @Override public void swim() { System.out.println("不会游泳"); } @Override public void quack() { System.out.println("不会叫");; } } public class WildDuck extends Duck { public WildDuck() { flyBehavior=new GoodFlyBehavior(); } @Override public void display() { System.out.println("野鸭子"); } } public interface FlyBehavior { public void fly(); } public class BadFlyBehavior implements FlyBehavior { @Override public void fly() { System.out.println("飞翔的不错"); } } public class GoodFlyBehavior implements FlyBehavior { @Override public void fly() { System.out.println("飞翔的很好"); } } public class NoFlyBehavior implements FlyBehavior { @Override public void fly() { System.out.println("不会飞翔"); } } public class Client { public static void main(String[] args) { WildDuck wildDuck=new WildDuck(); wildDuck.fly(); PekingDuck pekingDuck=new PekingDuck(); pekingDuck.fly(); //动态改变北京鸭飞翔 System.out.println("------改变了北京鸭的飞行"); pekingDuck.setFlyBehavior(new BadFlyBehavior()); pekingDuck.fly(); } }
-
策略模式的注意事项和细节
- 策略模式的关键是:分析项目中变化部分与不变部分。
- 策略模式的核心思想是:多用组合/聚合。少用继承;用行为类组合,而不是行为的继承。更有弹性。
- 体现了“对修改关闭,对扩展开放”原则,客户端增加行为不用修改源代码,只要添加一种策略(或者行为)即可,避免了使用多重转移语句
- 提供了可以替换继承关系的方法:策略模式将算法封装在独立的strategy类中使得你可以独立于其他context改变它,是它易于切换、易于理解、易于扩展。
- 需要注意的是:每天添加一个策略就要增加一个类,当策略过多就会导致类数目庞大。
-
- 职责链模式
-
基本介绍:
- 职责链模式:又叫责任链模式,为请求创建了一个接收者对象的链。这种模式对请求的发送者和接收者进行解耦。
- 职责链模式通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,以此类推。
- 这种设计模式属于行为型模式
-
代码
public class PurchaseRequest { private int type=0;//请求类型 private float price; private int id=0; public PurchaseRequest(int type, float price, int id) { this.type = type; this.price = price; this.id = id; } public int getType() { return type; } public float getPrice() { return price; } public int getId() { return id; } } public abstract class Approver { Approver approver;//下一个处理者 String name;//名字 public Approver(String name) { this.name=name; } //下一个处理者 public void setApprover(Approver approver) { this.approver = approver; } //处理请求的方法 public abstract void processRequest(PurchaseRequest purchaseRequest); } public class DepartmentApprover extends Approver { public DepartmentApprover(String name) { super(name); } @Override public void processRequest(PurchaseRequest purchaseRequest) { if(purchaseRequest.getPrice()<=5000) { System.out.println("请求编号:"+purchaseRequest.getId()+"被"+this.name+"处理了"); }else { approver.processRequest(purchaseRequest); } } } public class CollegeApprover extends Approver { public CollegeApprover(String name) { super(name); } @Override public void processRequest(PurchaseRequest purchaseRequest) { if(5000<purchaseRequest.getPrice()&&purchaseRequest.getPrice()<=10000) { System.out.println("请求编号:"+purchaseRequest.getId()+"被"+this.name+"处理了"); }else { approver.processRequest(purchaseRequest); } } } public class ViceSchoolMasterApprover extends Approver { public ViceSchoolMasterApprover(String name) { super(name); } @Override public void processRequest(PurchaseRequest purchaseRequest) { if(10000<purchaseRequest.getPrice()&&purchaseRequest.getPrice()<=30000) { System.out.println("请求编号:"+purchaseRequest.getId()+"被"+this.name+"处理了"); }else { approver.processRequest(purchaseRequest); } } } public class SchoolMasterApprover extends Approver { public SchoolMasterApprover(String name) { super(name); } @Override public void processRequest(PurchaseRequest purchaseRequest) { if(purchaseRequest.getPrice()>30000) { System.out.println("请求编号:"+purchaseRequest.getId()+"被"+this.name+"处理了"); }else { approver.processRequest(purchaseRequest); } } } public class Client { public static void main(String[] args) { PurchaseRequest purchaseRequest=new PurchaseRequest(1,31000, 1); DepartmentApprover departmentApprover=new DepartmentApprover("张主任"); CollegeApprover collegeApprover=new CollegeApprover("李院长"); ViceSchoolMasterApprover viceSchoolMasterApprover =new ViceSchoolMasterApprover("王副校长"); SchoolMasterApprover schoolMasterApprover =new SchoolMasterApprover("佟校长"); //需要将各个审批级别的下一个设置好处理人形成一个环形 departmentApprover.setApprover(collegeApprover); collegeApprover.setApprover(viceSchoolMasterApprover); viceSchoolMasterApprover.setApprover(schoolMasterApprover); schoolMasterApprover.setApprover(departmentApprover); schoolMasterApprover.processRequest(purchaseRequest); } }
-
职责链模式的注意事项和细节
- 将请求和处理分开,实现解耦,提高系统的灵活性。
- 简化了对象,使对象不需要知道链的结构。
- 性能会受到影响,特别是在链比较长的时候,因此需控制链中最大节点数量,一般通过在Handler中设置一个最大的节点数量,在setNext()方法中判断是否已经超过阈值,超过则不允许该链建立,避免出现超长链无意识地破坏系统性能。
- 调试不方便。采用了类似递归的方式,调试时逻辑可能比较复杂。
- 最佳应用场景:有多个对象处理同一个请求时,比如:多级请求,请假/加薪等审批流程、java web中tomcat对Encoding的处理、拦截器。
-