zoukankan      html  css  js  c++  java
  • 设计模式-装饰

    装饰,在某物件基础上加以修饰,装点,使得原本的朴素变得华丽,达到化腐朽为神奇的效果。比如我们从开发商买来的毛坯房,必然要进行室内装潢这么一项工程,什么简约风啊,北欧风啊,地中海,美式中式等等,当然萝卜青菜各有所爱,每个人装出的房子都各有差异,但不管何种风格,这都是对原本毛坯房的装饰,留给业主按照自己的喜好进行二次加工,这也是为什么有时候毛坯二手房比装修过的要好卖,有成品就一定得有半成品,这样才能把更多的选择留给用户,使得装饰成为可能。

    人靠衣装马靠鞍,当然不止是装修有这么神奇的效果,对于女生化妆来说我们也是深有体会,每当女友回家卸妆后素面朝天的时候我们的内心是崩溃的,有种当初相亲被骗的感觉。

    显而易见,女友每天出门之前进行的那场洗礼是多么的神圣,多么的不可或缺。诚然,化妆的过程对于男人来说充满了神秘色彩,但对于女人来说更像是一场洗礼,怀揣着信仰与敬畏感进行的一场仪式,最终会像魔法一般把自己的脸变得完美无瑕,更有甚者浓妆艳抹地连毛孔都看不到。

    作为研发人员,我们一定不能放过对于这项神秘工程的拆解分析,开始我们的工作。首先每个人要展示自己那必然有一个标准行为show(),我们将它抽象出来作为接口Showable。

    public interface Showable {
    public void show();//定义展示行为
    }

    当然,女友会这门功夫了,所以实现了此行为并施展其“美丽的脸庞”了,但此时只是原生态的素颜。

    public class Girl implements Showable{
    
    @Override
    public void show() {
    System.out.print("女孩的素颜");
    }
    
    }

    没什么复杂的,直接调用的话会是素面朝天直面惨淡的人生,这样当然达不到美颜效果了,何以登上人生巅峰。那么接下来要进行化妆了,这里必须依靠一种神秘而又昂贵的东西,化妆品登场了,它同样实现了Showable接口。

    public class Decorator implements Showable{//化妆品粉饰器
    
    Showable showable;//持有某个善于展示的家伙
    
    public Decorator(Showable showable) {//构造时注入这个家伙
    this.showable = showable;
    }
    
    @Override
    public void show() {
    System.out.print("粉饰(");//化妆品粉饰
    showable.show();//这家伙素面朝天的秀
    System.out.print(")");//粉饰打完收工
    }
    
    }

    我们可以发现,在构造化妆品类的时候可以把女孩给注入进来,目的在于调用女孩的show方法,但对于其原本的具体行为装饰器一无所知,并且没有加入任何逻辑限制,它所做的无非是“画龙点睛”,“锦上添花”。接下来我们来运行一下看结果。

    public class Client {
    public static void main(String[] args) {
    //用装饰器包裹女孩show出来
    new Decorator(new Girl()).show();
    //结果:粉饰(女孩的素颜)
    }
    }

    我们可以看到,只需要新建装饰器的时候把女孩给包装进去就得到了粉饰过的美颜,是不是非常简单?然而此时有女朋友会嫌弃了,“只是打粉底这么简单吗?眼霜呢?口红呢……”。

    好吧,为了满足女友的要求,我们得再多一些设计。想想看这些化妆品,不管是什么都有共同的特性,也就是说他们统统都可以装饰原生态的素颜展示方法show,那我们何不把这些特性抽象出来呢?开始行动,修改我们的装饰类。

    public abstract class Decorator implements Showable{
    
    protected Showable showable;
    
    public Decorator(Showable showable) {
    this.showable = showable;
    }
    
    @Override
    public void show() {
    showable.show();//直接调用不做加任何粉饰。
    }
    
    }

    我们把化妆品类给改成抽象类,重写show方法,但不做任何粉饰了,这里我们留给子类具体的某个化妆品去做装饰吧。化妆首先第一步一定要打底了,这里我们首先加入一个粉底类。

    public class FoundationMakeup extends Decorator{
    
    public FoundationMakeup(Showable showable) {
    super(showable);//调用化妆品父类注入
    }
    
    @Override
    public void show() {
    System.out.print("打粉底(");
    showable.show();
    System.out.print(")");
    }
    }

    我们可以看到粉底类继承了化妆品类,当然这个粉底的show方法一定要加以修饰了,在原生态的前后都进行了打粉底操作。同样地,打完粉底后再画个口红吧。

    public class Lipstick extends Decorator{
    
    public Lipstick(Showable showable) {
    super(showable);
    }
    
    @Override
    public void show() {
    System.out.print("涂口红(");
    showable.show();
    System.out.print(")");
    }
    }

    最后,我们把女友、粉底、口红层层包裹起来并运行,结果如愿以偿。

    public class Client {
    public static void main(String[] args) {
    //口红包裹粉底,再包裹女友。
    Showable madeupGirl = new Lipstick(new FoundationMakeup(new Girl()));
    madeupGirl.show();
    //运行结果:涂口红(打粉底(女孩的脸庞))
    }
    }

    如果女友对这种淡妆效果还是不满意,我们可以继续添加化妆品类,睫毛膏、眼线、眉笔、腮红等等等等,只需要层层包裹起来,最终实现女友浓妆艳抹的梦想。

    我们观察这种装饰器模式结构,是不是似曾相识呢?没错,其实装饰器模式在JDK里就有很多应用,比如Java IO包里的众多流处理类。

    new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));

    当然,流处理类当然要比我们的例子复杂的多,但其基本思想和我们去繁就简的例子异途同归,这些对象就好像是俄罗斯套娃一样层层包裹,层层装饰,每套一层就会多出一些功能出来,我们更可以自由搭配,实现不同的组合功能。

    所以,不管是女生化妆还是程序员写代码,我们都不可能弄出一个巨大的类然后去搞定所有事情,如此代码会越堆积越多,难于维护,功能扩展更是举步维艰。我们都需要有这种设计思想,每个化妆品部件各司其职,不做和自己不相关的事,然后把部件层层叠加,并根据需求组装成型,以达最终的装饰目的。

    愿你眼中有光芒,活成你想要的模样
  • 相关阅读:
    遍历页面的控件
    数字转换成中文大写,英文大写
    Infopath 2010 日期相减计算
    SharePoint 2010 表单之重复表
    癌(Cancer)是如何产生的
    Linux中的缩写都是什么意思——转自博客园博主super119的Super's Blog
    不使用printf系列库函数,将十进制数以十六进制数形式输出
    第二十九讲 深入解析ASP.NET架构
    第三十八 ASP.NET多线程编程(二)
    第三十一讲 数据集和数据库的同步-DataAdapter的使用
  • 原文地址:https://www.cnblogs.com/SmallStrange/p/13895164.html
Copyright © 2011-2022 走看看