ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

设计模式之装饰器模式(Decorator Design Pattern)

2021-02-08 11:01:51  阅读:206  来源: 互联网

标签:Pattern void System Design human println 设计模式 public out


装饰器模式是常用设计模式之一,通过一个装饰类来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

装饰器模式与代理模式非常像,区别是代理模式是原始功能上附加功能,而装饰器模式是增强原始功能。

代理模式:我(代理)不是你(原始类),我只是代表你的(部分或全部)能力,不会改变你的能力;

装饰器模式:我(装饰器)就是你(原始类),我是你的伪装,不仅有你的全部能力,还可以改变你的能力;

装饰类有两个特点:完全包装原始类和层层包装

  • 要完全包装原始类,装饰类必须与原始类实现同一个接口,并实现相同的方法。装饰类通过组合原始类,在每个方法中调用原始类的方法。
//人类
interface HumanBeing {
  //速度
  public void velocity();
  //反应
  public void reaction();
  //视野
  public void vision();
}

//正常人
class Human implements HumanBeing {
    //速度
    public void velocity(){
        System.out.println("速度:每小时走10公里");
    }
    //反应
    public void reaction(){
        System.out.println("反应:打不到飞行中的蚊子");
    }
    //视野
    public void vision(){
        System.out.println("视野:可看到10公里外事物");
    }
}


//钢铁侠,普通人穿上的钢铁服
class IronMan implements HumanBeing {

    HumanBeing human;
  
    public IronMan(HumanBeing human) {
        System.out.println("--变身钢铁侠------------");
        this.human = human;
    }

    //速度
    public void velocity(){
        this.human.velocity();
        System.out.println("速度:时速加上500公里,会飞了");
    }
    //反应
    public void reaction(){
        this.human.reaction();
        System.out.println("反应:变快100倍,可以接住子弹");
    }
    //视野
    public void vision(){
        this.human.vision();
        System.out.println("视野:视野增加到了30公里,同时看到多个目标");
    }
}


//圣斗士,普通人穿上的圣衣
class holyWarriors implements HumanBeing {

    HumanBeing human;
  
    public holyWarriors(HumanBeing human) {
        System.out.println("--变身圣斗士------------");
        this.human = human;
    }

    //速度
    public void velocity(){
        this.human.velocity();
        System.out.println("速度:时速加上200公里");
    }
    //反应
    public void reaction(){
        this.human.reaction();
        System.out.println("反应:变快1000倍,可以削掉飞行中蚊子的翅膀");
    }
    //视野
    public void vision(){
        this.human.vision();
        System.out.println("视野:视野添加了50公里");
    }
}

public class Demo {
    public static void main(String[] args) {
        HumanBeing human= new Human();
        //变身钢铁侠
        physicalExamination(new IronMan(human));
        //变身圣斗士
        physicalExamination(new holyWarriors(human));
    }

    //体检
    private static void physicalExamination(HumanBeing human){
        human.velocity();
        human.reaction();
        human.vision();
    }
}

//执行结果
--变身钢铁侠------------
速度:每小时走10公里
速度:时速加上500公里,会飞了
反应:打不到飞行中的蚊子
反应:变快100倍,可以接住子弹
视野:可看到10公里外事物
视野:视野增加到了30公里,同时看到多个目标
--变身圣斗士------------
速度:每小时走10公里
速度:时速加上200公里
反应:打不到飞行中的蚊子
反应:变快1000倍,可以削掉飞行中蚊子的翅膀
视野:可看到10公里外事物
视野:视野添加了50公里

通过IronMan、holyWarriors 两个类包装,对正常人的能力进行了增强。

  • 装饰类还有一个特点,就是可以层层包装。
public class Demo {
    public static void main(String[] args) {
        HumanBeing human= new Human();
        //变身钢铁侠之后又变身圣斗士,普通人有了钢铁侠和圣斗士的能力
        physicalExamination(new holyWarriors(new IronMan(human)));
    }

    //体检
    private static void physicalExamination(HumanBeing human){
        human.velocity();
        human.reaction();
        human.vision();
    }
}

//执行结果
--变身钢铁侠------------
--变身圣斗士------------
速度:每小时走10公里
速度:时速加上500公里,会飞了
速度:时速加上200公里
反应:打不到飞行中的蚊子
反应:变快100倍,可以接住子弹
反应:变快1000倍,可以削掉飞行中蚊子的翅膀
视野:可看到10公里外事物
视野:视野增加到了30公里,同时看到多个目标
视野:视野添加了50公里

类图: 

 

装饰模式在实际使用中每一个装饰类都需要完全包装原始类,但并不是每个方法(能力)都会改变。如果每个装饰类都要去实现调用原始类的方法,显然这不符合KISS、DRY原则。所以会让装饰类继承一个抽象装饰类,由这个抽象装饰类调用原始类的方法。真正的装饰类扩展需要改变能力的方法。现在我们把人类增加一种能力“变形”,看怎么使用抽象装饰类。

//人类
public interface HumanBeing {
    //速度
    public void velocity();
    //反应
    public void reaction();
    //视野
    public void vision();
    
    //变形
    public void deformation();
}


//正常人
public class Human implements HumanBeing {
    //速度
    public void velocity(){
        System.out.println("速度:每小时走10公里");
    }
    //反应
    public void reaction(){
        System.out.println("反应:打不到飞行中的蚊子");
    }
    //视野
    public void vision(){
        System.out.println("视野:可看到10公里外事物");
    }

    //变形
    public void deformation(){
        System.out.println("变形:不能变形");
    }
}

//抽象装饰类:超人
public abstract class Superman implements HumanBeing {
    HumanBeing human;

    public Superman(HumanBeing human) {
        this.human = human;
    }

    //速度
    public void velocity(){
        this.human.velocity();
    }
    //反应
    public void reaction(){
        this.human.reaction();
    }
    //视野
    public void vision(){
        this.human.vision();
    }

    //变形
    public void deformation(){
        this.human.deformation();
    }
}


//钢铁侠,继承超人
public class IronMan extends Superman {

    public IronMan(HumanBeing human) {
        super(human);
        System.out.println("--变身钢铁侠------------");
    }

    //速度
    public void velocity(){
        super.velocity();
        System.out.println("速度:时速加上500公里,会飞了");
    }
    //反应
    public void reaction(){
        super.reaction();
        System.out.println("反应:变快100倍,可以接住子弹");
    }
    //视野
    public void vision(){
        super.vision();
        System.out.println("视野:视野增加到了30公里,同时看到多个目标");
    }

    //没有变形能力,所有不需要重写变形

}

//圣斗士,继承超人
public class holyWarriors extends Superman {

    public holyWarriors(HumanBeing human) {
        super(human);
        System.out.println("--变身圣斗士------------");
    }

    //速度
    public void velocity(){
        super.velocity();
        System.out.println("速度:时速加上200公里");
    }
    //反应
    public void reaction(){
        super.reaction();
        System.out.println("反应:变快1000倍,可以削掉飞行中蚊子的翅膀");
    }
    //视野
    public void vision(){
        super.vision();
        System.out.println("视野:视野添加了50公里");
    }

    //没有变形能力,所有不需要重写变形
}

//橡胶人,继承超人
public class RubberMan extends Superman {

    public RubberMan(HumanBeing human) {
        super(human);
        System.out.println("--变身橡胶人------------");
    }

    //变形
    public void deformation(){
        super.deformation();
        System.out.println("变形:可以变长");
    }
}

类图: 

 

装饰模式运用的是多用组合少用继承的设计思想。

装饰类的运用比较多,比较有代表性的是java.io类库:

 

标签:Pattern,void,System,Design,human,println,设计模式,public,out
来源: https://blog.csdn.net/xjj1314/article/details/113625676

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有