设计模式【装饰者模式】+ 皇帝新衣

58 阅读3分钟

装饰者模式

  • 动态的给对象添加一些额外的职责,正常添加额外操作我们成为功能的扩展, Java中我们通过继承多态实现功能的扩展,但是这些是静态的我们必须在程序编译前 实现这些扩展类,而且我们需要尽可能实现所有的扩展。但是装饰着模式的特点就是 动态的扩展功能

实际案例

  • 炎炎夏日刚睡醒的你身上一丝不挂,起床之后你需要做的事情就是穿衣服(装饰)。 不同的人习惯不一样,有的人会选择先串上衣-->再穿裤子。有的人喜欢先穿裤子--> 在穿上衣。有的人喜欢先穿裤子-->做些其他事情-->在穿上衣。总之不同的人装饰自己的习惯不一样。 就像是100个人心中有100个哈姆雷特。

对应Java分析

  • 一丝不挂的你是一个人类,这里人类就是一个接口 这里简单归结有两个行为(吃饭+穿衣) 下面我们会有人类装饰自己的行为,(穿上衣+穿裤子+戴帽子+戴眼镜+围围巾...) 人类(Human)一个接口。 你(Person)人类的具体对象 装饰行为(Decorate...)

优点

  • 实际上我们装饰自己的行为很不确定,或有很多,比如现在增加一个戴口罩的装饰行为我们 只需要在实现一个装饰类就行了。在若干装饰中我们装饰的顺序不一样,我们总不能在代码中全部实现 这是不科学的。在装饰者模式中我们可以避免这个缺陷,顺序完全有用户决定。实现动态的给Person类, 扩展功能。

code

public interface Human
{
    //吃
    public void eat();
    
    //穿
    public void decorate();
    
    //认可
    public String approve(String approve);
}
  • 我们首先定义个抽象人类的描述。一个人肯定拥有吃的行为,穿的行为,还有这个人在社会中的地位
  • 然后我们根据这些特性,构建了一个文明的物种普通人
public class Person implements Human
{
​
    @Override
    public void eat()
    {
        System.out.println("xxxx喜欢吃烧烤");
        
    }
​
    @Override
    public void decorate()
    {
        System.out.println("xxxx在穿袜子");
        
    }
​
    @Override
    public String approve(String approve)
    {
        approve+="_xxxx";
        return approve;
    }
​
}
  • 人都是需要加以装扮的,不可能像出生时一样,所以我们需要在Person的基础上进行封装,方便后续装饰
public abstract class Decorate implements Human
{
​
    private Human human;
​
    public Decorate(Human human)
    {
        this.human = human;
    }
​
    @Override
    public void eat()
    {
        human.eat();
​
    }
​
    @Override
    public void decorate()
    {
        human.decorate();
    }
​
    @Override
    public String approve(String approve)
    {
        return human.approve(approve);
    }
    
    
}
  • Decorate是我们暴露出去的人类,这里将Person想象成我们真挚的心。终究都会穿上一层纱才出去。

穿上新衣

  • 现在我们将我们自己穿上人生中第一套衣服
public class UpClothDecorate extends Decorate
{
​
    public UpClothDecorate(Human human)
    {
        super(human);
    }
​
    private void eatBeer()
    {
        System.out.println("吃Beer");
    }
    
    private void holdCloth()
    {
        System.out.println("穿上衣");
    }
​
    @Override
    public void eat()
    {
        super.eat();
        eatBeer();
    }
​
    @Override
    public void decorate()
    {
        super.decorate();
        holdCloth();
    }
​
    @Override
    public String approve(String approve)
    {
        return super.approve(approve)+"_服装协会";
    }
​
}
  • 上面的UpClothDecorate就是为我们准备的衣服。至于何时传,如何传使我们决定的

测试

public class Test
{
    public static void main(String[] args) 
    {
        Human zxh = new Person();
        Decorate decorate = new UpClothDecorate(new UpCapDecorate(zxh));
        decorate.decorate();
        System.out.println(decorate.approve("请求认证是否通过?"));
    }
}
  • 上面的代码就是我们首先选择穿上衣服,如果还有别的装饰品,我们可以继续穿戴。比如还有帽子,那么我们就可以据需decorate 。

image-20211019145305800.png