链式设计模式

链式设计模式——装饰器模式和职责链模式

 装饰模式 

定义: 指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。

结构

装饰(Decorator)模式中的角色:

  • 抽象构件(Component)角色 :定义一个抽象接口以规范准备接收附加责任的对象。
  • 具体构件(Concrete Component)角色 :实现抽象构件,通过装饰角色为其添加一些职责。
  • 抽象装饰(Decorator)角色 : 继承或实现抽象构件,并包含具体构件的实例,可以通过其子 类扩展具体构件的功能。
  • 具体装饰(ConcreteDecorator)角色 :实现抽象装饰的相关方法,并给具体构件对象添加附 加的责任

结构图

例子

以快餐店买饭有不同配菜为例

//快餐接口
public abstract class FastFood {
 private float price;
 private String desc;
 public FastFood() {
 }
 public FastFood(float price, String desc) {
 this.price = price;
 this.desc = desc;
 }
 public void setPrice(float price) {
 this.price = price;
 }
 public float getPrice() {
 return price;
 }
 public String getDesc() {
 return desc;
 }
 public void setDesc(String desc) {
 this.desc = desc;
 }
 public abstract float cost();  //获取价格
}




 //炒饭
public class FriedRice extends FastFood {
 public FriedRice() {
 super(10, "炒饭");
 }
 public float cost() {
 return getPrice();
 }
 }



 //炒面
public class FriedNoodles extends FastFood {
 public FriedNoodles() {
 super(12, "炒面");
 }
 public float cost() {
 return getPrice();
 }
 }



 //配料类
public abstract class Garnish extends FastFood {
 private FastFood fastFood;
 public FastFood getFastFood() {
 return fastFood;
 }
 public void setFastFood(FastFood fastFood) {
 this.fastFood = fastFood;
 }
 public Garnish(FastFood fastFood, float price, String desc) {
 super(price,desc);
 this.fastFood = fastFood;
 }
 }



 //鸡蛋配料
public class Egg extends Garnish {
 public Egg(FastFood fastFood) {
 super(fastFood,1,"鸡蛋");
 }
 public float cost() {
 return getPrice() + getFastFood().getPrice();
 }

    @Override
    public String getDesc() {
        return super.getDesc() + getFastFood().getDesc();
    }
 }



 //培根配料
public class Bacon extends Garnish {
    public Bacon(FastFood fastFood) {
        super(fastFood,2,"培根");
    }
    @Override
    public float cost() {
        return getPrice() + getFastFood().getPrice();
    }
    @Override
    public String getDesc() {
        return super.getDesc() + getFastFood().getDesc();
    }
 }



 //测试类
public class Client {
    public static void main(String[] args) {
        //点一份炒饭
        FastFood food = new FriedRice();
        //花费的价格
        System.out.println(food.getDesc() + " " + food.cost() + "元");
        System.out.println("========");
        //点一份加鸡蛋的炒饭
        FastFood food1 = new FriedRice();
        food1 = new Egg(food1);
        //花费的价格
        System.out.println(food1.getDesc() + " " + food1.cost() + "元");
        System.out.println("========");
        //点一份加培根的炒面
        FastFood food2 = new FriedNoodles();
        food2 = new Bacon(food2);
        //花费的价格
        System.out.println(food2.getDesc() + " " + food2.cost() + "元");
    }
 }

好处

  • 装饰模式可以带来比继承更加灵活性的扩展功能,使用更加方便,可以通过组合不同的装饰对象 来获取具有不同行为状态的多样化的结果。
  • 装饰模式比继承更具良好的扩展性,完美的遵循开闭 原则,继承是静态的附加责任,装饰者则是动态的附加责任。
  • 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以 动态扩展一个实现类的功能

职责链模式

定义:为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对 象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处 理它为止。

结构

职责链模式主要包含以下角色:

  • 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
  • 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请 求,如果可以处理请求则处理,否则将该请求转给它的后继者。
  • 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节 和请求的传递过程。

结构图

例子

以请假流程为例

 //请假条
public class LeaveRequest {
 private String name;//姓名
private int num;//请假天数
    private String content;//请假内容
    public LeaveRequest(String name, int num, String content) {
        this.name = name;
        this.num = num;
        this.content = content;
    }
    public String getName() {
        return name;
    }
    public int getNum() {
        return num;
    }
    public String getContent() {
        return content;
    }
 }




 //处理者抽象类
public abstract class Handler {
    protected final static int NUM_ONE = 1;
    protected final static int NUM_THREE = 3;
    protected final static int NUM_SEVEN = 7;
    //该领导处理的请假天数区间
    private int numStart;
    private int numEnd;
    //领导上面还有领导
    private Handler nextHandler;
    //设置请假天数范围 上不封顶
    public Handler(int numStart) {
        this.numStart = numStart;
    }
    //设置请假天数范围
    public Handler(int numStart, int numEnd) {
        this.numStart = numStart;
        this.numEnd = numEnd;
    }
    //设置上级领导
    public void setNextHandler(Handler nextHandler){
        this.nextHandler = nextHandler;
    }
    //提交请假条
    public final void submit(LeaveRequest leave){
        if(0 == this.numStart){
            return;
        }
        //如果请假天数达到该领导者的处理要求
        if(leave.getNum() >= this.numStart){
            this.handleLeave(leave);
            //如果还有上级 并且请假天数超过了当前领导的处理范围
            if(null != this.nextHandler && leave.getNum() > numEnd){
                this.nextHandler.submit(leave);//继续提交
            } else {
                System.out.println("流程结束");
            }
        }
    }
    //各级领导处理请假条方法
    protected abstract void handleLeave(LeaveRequest leave);
 }




 //小组长
public class GroupLeader extends Handler {
    public GroupLeader() {
        //小组长处理1-3天的请假
        super(Handler.NUM_ONE, Handler.NUM_THREE);
    }
    @Override
    protected void handleLeave(LeaveRequest leave) {
        System.out.println(leave.getName() + "请假" + leave.getNum() + 
"天," + leave.getContent() + "。");
        System.out.println("小组长审批:同意。");
    }
 }




 //部门经理
public class Manager extends Handler {
    public Manager() {
        //部门经理处理3-7天的请假
        super(Handler.NUM_THREE, Handler.NUM_SEVEN);
    }
    @Override
    protected void handleLeave(LeaveRequest leave) {
        System.out.println(leave.getName() + "请假" + leave.getNum() + 
"天," + leave.getContent() + "。");
        System.out.println("部门经理审批:同意。");
    }
 }




 //总经理
public class GeneralManager extends Handler {
    public GeneralManager() {
        //部门经理处理7天以上的请假
        super(Handler.NUM_SEVEN);
    }
    @Override
    protected void handleLeave(LeaveRequest leave) {
        System.out.println(leave.getName() + "请假" + leave.getNum() + 
"天," + leave.getContent() + "。");
        System.out.println("总经理审批:同意。");
    }

 }



 //测试类
public class Client {
 public static void main(String[] args) {
 //请假条来一张
LeaveRequest leave = new LeaveRequest("小花",5,"身体不适");
 //各位领导
GroupLeader groupLeader = new GroupLeader();
 Manager manager = new Manager();
 GeneralManager generalManager = new GeneralManager();
 groupLeader.setNextHandler(manager);//小组长的领导是部门经理
manager.setNextHandler(generalManager);//部门经理的领导是总经理
//之所以在这里设置上级领导,是因为可以根据实际需求来更改设置,如果实战中上级领
导人都是固定的,则可以移到领导实现类中。
//提交申请
groupLeader.submit(leave);
 }
 }

优点

  • 降低了对象之间的耦合度 该模式降低了请求发送者和接收者的耦合度。 增强了系统的可扩展性 可以根据需要增加新的请求处理类,满足开闭原则。
  • 增强了给对象指派职责的灵活性 当工作流程发生变化,可以动态地改变链内的成员或者修改它们的次序,也可动态地新增或者删除 责任。
  • 责任链简化了对象之间的连接 一个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多 的 if 或者 if···else 语句。
  • 责任分担 每个类只需要处理自己该处理的工作,不能处理的传递给下一个对象完成,明确各类的责任范围, 符合类的单一职责原则。

缺点

  • 不能保证每个请求一定被处理。
  • 由于一个请求没有明确的接收者,所以不能保证它一定会被处理, 该请求可能一直传到链的末端都得不到处理。
  • 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
  • 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而 导致系统出错,如可能会造成循环调用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值