从一个手办扯到装饰者设计模式

装饰者模式定义:

装饰模式可以动态的给一个对象增加一些额外的功能(增强功能) 相比于继承,装饰模式能对不支持继承的类进行增强;并且比继承更灵活,不需要生成大量的子类。

优缺点:

优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:多层装饰比较复杂。

应用场景:

  1. 扩展一个类的功能
  2. 动态增加功能,动态撤销
  3. Java IO 源码

微剧场:

上次做智能遥控器,投入市场之后销售惨淡,阿呆被老板狠狠的批评了一顿,这几天心情十分郁闷。但是郁闷归郁闷,生活还是要继续下去的,于是阿呆决定买一个手办安慰一下自己。

但刚买回来两天,阿呆静静看着自己手中的王者荣耀大乔的手办,顿时感觉审美有些疲劳,怎么办呢,看来只能动用我的钞能力了,于是阿呆就陆续买了大乔其他风格的手办,短短几天,手办便占据了阿呆的整个屋子,简直寸步难行了。这个时候,阿呆想,能不能用我平常所学的编程知识来解决我现在的苦恼呢。

Hello,World !阿呆脑海中陆续显出来这几个字。好吧,显然不能。看来靠阿呆自己解决这个问题几乎没有什么希望了,正当阿呆一筹莫展之际,阿呆想到了第二篇笔记观察者模式出来过一次后来就被作者忘掉的角色二呆,于是急忙给二呆发短信求助。

阿呆:二呆,我最近喜欢收集大乔的手办,可是我现在屋子里已经没有地方放置新的手办了,但是官方又推出了很多款其他风格的手办,想买又没有地方放了,好苦恼。

二呆:有钱人的生活就是这么的简单且枯燥,容我稍稍思考片刻

一个小时后....

两个小时后....

阿呆你这样理解,我们把你第一个买的大乔手办想象成java中的一个类,而你其他的大乔手办看作成它的子类,也就是你现在既想要很多风格的大乔手办,又不想买很多大乔手办对不对?

阿呆:知我者莫过于二呆了,放心,明天我就去求这个世界上最帅气最善良最智慧的韩数大大把你复活,那么二呆,我下面应该怎么办呢?

二呆:装饰者设计模式就可以完美解决这个问题,你想,你去买一个没有穿衣服的大乔手办(咳咳,笔者也不知道怎么说了,裸办?),就是那种还没有后期穿服装的手办模型,然后你再去网上买很多大乔的衣服,不就可以实现一个手办,无数大乔的目的了吗?

阿呆:机智,那个,先不聊了,韩数说他不想往下写了,回见,拜拜。

二呆:嘟嘟嘟

想到这里大家差不多已经明白了,传统的方法对一个类的功能的增强,往往是增加一个这个类的子类,然后重写我们需要增强的方法,当然,一个两个子类没有什么问题,如果随着业务的复杂,成百上千个子类势必会增加我们开发人员维护的负担。更何况,有很多类是禁止继承的,为了解决这个问题呢,装饰者模式就应运而生了。我们需要增强的类就是那个手办,装饰者模式呢就是在不改变手办结构的情况下,为她穿上衣服,增强它的颜值。

还不明白?上代码

代码实战:

首先,定义手办相关的接口:

//大乔手办接口
public interface GarageKit {

//定义一个方法,还没有穿上衣服的手办
public void bodyWithClothes();

}

然后我们声明一个类作为大乔手办实现这个接口,完成具体的功能。并把这个类设置为不可继承。

//大乔手办
final class DaQiaoGarageKit implements GarageKit {

@Override
public void bodyWithClothes() {
System.out.println("嘤嘤嘤,我现在还没有穿好衣服,不漂亮,不能出门(羞耻)");

}

}

同样的,我们定义装饰者相关的接口:


//装饰者接口,定义装饰者的行为
public interface Decorator extends GarageKit {

//给大乔穿衣服
public void getClothes();

}

然后我们声明一个类作为实际的装饰者。

 //大乔装饰者实现
public class DaQiaoDecorator implements Decorator{
​
    
    //定义内部成员变量 DaQiaoGarageKit
    private DaQiaoGarageKit daQiaoGarageKit = null;
    
    public DaQiaoDecorator(GarageKit garageKit) {
        this.daQiaoGarageKit  =(DaQiaoGarageKit) garageKit;
        
    }
    
    
    //为大乔穿上衣服
    @Override
    public void getClothes() {
        // TODO Auto-generated method stub
        System.out.println("好了,我现在穿好衣服啦,可以出门了");
    }
​
​
    //在这里增强DaQiaoGarageKit类的功能,使其拥有穿衣服的能力。
    @Override
    public void bodyWithClothes() {
        // TODO Auto-generated method stub
        daQiaoGarageKit.bodyWithClothes();
        getClothes();
    }
​


​
}
​ 

测试:

public class Test {

public static void main(String[] args) {

// TODO Auto-generated method stub
GarageKit garageKit = new DaQiaoGarageKit();
Decorator decorator = new DaQiaoDecorator(garageKit);
decorator.bodyWithClothes();

}

}

OUTPUT:

嘤嘤嘤,我现在还没有穿好衣服,不漂亮,不能出门(羞耻)
好了,我现在穿好衣服啦,可以出门了

总结:

本篇文章较为简单的阐述了装饰者模式的优缺点,虽然这次微剧场部分有点尬,装饰者设计模式也是实际开发中使用的较为频繁的设计模式,在java IO中也有广泛的应用,看下面一行代码:

 BufferedInputStream in = new BufferedInputStream(new FileInputStream("d:\\1.txt"));

是不是有些许的熟悉呢,感兴趣的小伙伴可以自行查找资料了解,本系列笔记相关源码已经开源至github,需要的可以前去下载。我是韩数,练习代码时长两年半的大学生一枚,我们下篇文章再见!

暂无评论

文艺中二理工男,技术极客程序员

发表评论