zoukankan      html  css  js  c++  java
  • 大话设计模式读书笔记(装饰模式)

    人物:大鸟,小菜

    事件:小菜要去约会,不知道穿什么,怎么搭配,大鸟借着搭配衣服这件事,给小菜讲了装饰模式


    装饰模式:

    1.大鸟让小菜通过代码实现装扮,大鸟指出了小菜的不足

    2.在结合了开放封闭原则后,小菜进行了第二次装扮,大鸟依然指出了小菜的正确和失误,引出了装饰模式

    3.小菜在领悟了装饰模式后,进行了第三次装扮

    4.最后对装扮模式进行了小结

    小菜的第一次装扮

    @Slf4j
    public class Person {
        private String name;
    
        public Person(String name) {
            this.name = name;
        }
    
        public void wearTShirts() {
            log.info("大T恤");
        }、
    
        public void wearBigTrouser() {
            log.info("垮裤");
        }
    
        public void wearSneakers() {
            log.info("破球鞋");
        }
    
        public void wearSuit() {
            log.info("穿西装");
        }
    
        public void wearTie() {
            log.info("领带");
        }
    
        public void wearLeatherShoes() {
            log.info("皮鞋");
        }
    
        public void show() {
            log.info("装扮的:{}", name);
        }
    }

    客户端:

    @Slf4j
    public class PersonWear {
        public static void main(String[] args) {
            Person xc = new Person("小菜");
            log.info("第一种装扮:");
            xc.wearSuit();
            xc.wearTie();
            xc.wearLeatherShoes();
            xc.show();
        }
    }

    大鸟:现在需要增加超人的装扮,需要怎么改呢?

    小菜的第二次装扮

    在学习了开放-封闭原则后,小菜出了第二次装扮

     Person类:

    @Slf4j
    public class Person {
        private String name;
    
        public Person(String name) {
            this.name = name;
        }
    
        public void show() {
            log.info("装扮的:{}", name);
        }
    }

    服饰抽象类:

    public abstract class Finery {
        public abstract void show();
    }

    各种服饰子类:

    @Slf4j
    public class TShirts extends Finery {
        @Override
        public void show() {
            log.info("大T恤");
        }
    }
    @Slf4j
    public class BigTrouser extends Finery {
        @Override
        public void show() {
            log.info("垮裤");
        }
    }
    @Slf4j
    public class Sneakers extends Finery {
        @Override
        public void show() {
            log.info("破球鞋");
        }
    }

    ......

    客户端代码:

    @Slf4j
    public class PersonWear {
        public static void main(String[] args) {
            Person xc = new Person("小菜");
            log.info("第一种装扮:");
            Finery dtx = new TShirts();
            Finery kk = new BigTrouser();
            Finery pqx = new Sneakers();
    
            dtx.show();
            kk.show();
            pqx.show();
            xc.show();
        }
    }

    小菜:这下结果和之前的一样,而且面向了对象,只要有新的服饰,再增减子类即可

    大鸟:但是这段代码还是有点问题:

    dtx.show();
    kk.show();
    pqx.show();
    xc.show();

    这里显式地放在了外面,这就好比当着大家的面在穿衣服,其实应该在内部组装,我们要把所需的功能按正确的顺序串联起来进行控制,于是这里就引入了新的模式--装饰模式

    装饰模式

    装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。

    它的实现:

    Component类,这是最原始的对象,是一个对象接口,可以给对象动态添加职责

    public abstract class Component {
        public abstract void Operation();
    }

    ConcreteComponent类,定义一个具体的对象,是最基本接口的实现,我们要装饰它

    @Slf4j
    public class ConcreteComponent extends Component {
        @Override
        public void Operation() {
            log.info("具体对象的操作");
        }
    }

    Decorator类,装饰抽象类,继承了Component,从外类扩展Component功能

    public class Decorator extends Component {
        protected Component component;
    
        public void setComponent(Component component) {
            this.component = component;
        }
    
        @Override
        public void Operation() {
            if (component != null) {
                component.Operation();
            }
        }
    }

    ConcerteDecoratorA类和ConcerteDecoratorB类,先执行Operation()方法,再执行addedState赋值或addedBehavior方法调用,相当于进行了装饰

    @Slf4j
    public class ConcerteDecoratorA extends Decorator {
        private String addedState;
    
        @Override
        public void Operation(){
            this.Operation();
            addedState = "New State";
            log.info("具体装饰对象A的操作");
        }
    }
    @Slf4j
    public class ConcreteDecoratorB extends Decorator {
    
        @Override
        public void Operation() {
            this.Operation();
            AddedBehavior();
            log.info("具体装饰对象B的操作");
        }
    
        private void AddedBehavior() {
            //本类独有的方法,以作区别
        }
    }

    客户端代码,先实例化对象c,再用ConcerteDecoratorA的实例化对象d1来包装c,再用ConcreteDecoratorB实例话的对象d2包装d1,最终再执行d2的Operation()

    public static void main(String[] args) {
        ConcreteComponent c = new ConcreteComponent();
        ConcreteDecoratorA d1 = new ConcreteDecoratorA();
        ConcreteDecoratorB d2 = new ConcreteDecoratorB();
    
        d1.setComponent(c);
        d2.setComponent(d1);
        d2.Operation();
    }

    小菜:原来装饰模式是利用setComponent来对对象进行包装,这样每个装饰对象的实现就和如何使用这个对象分开了,每个装饰对象只用关心自己的功能

    大鸟:那我们刚刚用的Person()类,是属于Component类还是ConcreteComponent类呢?

    小菜:我觉得如果只有ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类,同理,如果没有ConcreteDecoratorA和ConcreteDecoratorB,而是只有一个ConcreteDecorator类,那么ConcreteDecorator类和Decorator类也可以合二为一,这里我们就不必用Component类,直接让服饰类Decorator类继承人类ConcreteComponent即可。

    小菜的第三次装扮

    Person类(ConcreteComponent类)

    @Slf4j
    public class Person {
    public Person() {}

    private String name;

    public Person(String name) {
    this.name = name;
    }

    public void show() {
    log.info("装扮的:{}", name);
    }
    }

    服饰类(Decorator)

    public class Finery extends Person {
    protected Person component;

    public void Decorate(Person component) {
    this.component = component;
    }

    @Override
    public void show() {
    if (component != null) {
    component.show();
    }
    }
    }

    具体服饰类:

    @Slf4j
    public class TShirts extends Finery {
        @Override
        public void show() {
    super.show(); log.info(
    "大T恤"); } } @Slf4j public class Sneakers extends Finery { @Override public void show() {
    super.show(); log.info(
    "破球鞋"); } } @Slf4j public class BigTrouser extends Finery { @Override public void show() {
    super.show(); log.info(
    "垮裤"); } }

    小结

    1.装饰模式:

    装饰模式是为已有功能动态地添加更多功能的一种方式

    2.什么时候用装饰模式?

    在最初设计系统时,当系统需要新的功能,就要向旧的类中添加新的代码,这些新加的代码通常装饰了原有类的核心职责和主要行为,它们在主类添加了新的字段,新的逻辑,增加了主类的复杂度,而新加入的东西可能只是为了满足某个特殊的需求。而装饰模式把要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此要执行特殊行为时,客户代码就可以在运行时有选择地,按顺序地使用装饰功能包装对象了

     3.优点:

        (1)把类中的装饰功能从类中搬移去除,这样可以简化原有的类

        (2)有效地把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑

  • 相关阅读:
    011 Go语言基础之map
    009 Go语言基础之切片
    计算机组成原理 — GPU 图形处理器
    js 实现各浏览器全屏
    js 实现各浏览器全屏
    IIS-真正解决ASP.NET每一个页面首次访问超级慢的问题
    IIS-真正解决ASP.NET每一个页面首次访问超级慢的问题
    首次启动速度慢的问题记录IIS性能优化
    首次启动速度慢的问题记录IIS性能优化
    C#-执行cmd命令,获取结果
  • 原文地址:https://www.cnblogs.com/wencheng9012/p/13373994.html
Copyright © 2011-2022 走看看