zoukankan      html  css  js  c++  java
  • 再战设计模式(十)之装饰模式

    装饰模式

    职责:

    动态的为一个对象添加新的功能

    装饰模式i是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的新功能,使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀

      现在假设:有一辆汽车 ,我们需要他实现 会飞,会游泳,会自动驾驶的功能,我们没有用设计模式之前应该是 定义一个接口,定义3个子类去实现. 那么我现在有需要他既会飞又会游泳呢?是不是还需要继续实现和extends

    如果现在要求3种都会呢?那么我们是不是需要继续extends 

    现在我们用装饰模式来实现下这的功能

    类图如下:

     代码:

    /**
     * compent 组件 具有真实对象和 装饰对象相同的接口,这样
     * 客户端可以和真实的对象一样和装饰对象交互
     */
    public interface CarComponent {
        void move();
    }
    /**
     * 真实的类
     */
    public class Car implements CarComponent {
        @Override
        public void move() {
            System.out.println("真实的汽车");
        }
    }
    /**
     * 装饰的类
     */
    public class DecoratorCar implements CarComponent{
    
        protected CarComponent carComponent;
    
        public DecoratorCar(CarComponent carComponent) {
            this.carComponent = carComponent;
        }
    
        @Override
        public void move() {
            carComponent.move();
        }
    }
    
    public class FlyCar extends DecoratorCar {
        public FlyCar(CarComponent carComponent) {
            super(carComponent);
        }
    
        public void fly(){
            System.out.println("汽车飞起来了");
        }
    
        @Override
        public void move() {
          super.move();
          fly();
        }
    }
    
    public class WaterCar extends DecoratorCar {
    
        public WaterCar(CarComponent carComponent) {
            super(carComponent);
        }
    
        public  void swim(){
            System.out.println("i'm siwmming ");
    
        }
        @Override
        public void move() {
    
          super.move();
        swim();
        }
    }
    
    
    
    
    public class AICar extends DecoratorCar {
        public AICar(CarComponent carComponent) {
            super(carComponent);
        }
    
        public  void ai(){
            System.out.println("auto move car");
        }
        @Override
        public void move() {
           super.move();
           ai();
        }
    }
    
    
    public class Clinet {
    
        public static void main(String[] args) {
    
            CarComponent car = new Car();
            car.move();
    
            DecoratorCar car1 = new DecoratorCar(new FlyCar(car));
            car1.move();
            System.out.println("水车和ai组合===============");
    
            DecoratorCar car2 = new WaterCar(new AICar(car));
            car2.move();
        }
    }

    现在我们有3个子类,分别会飞  会游泳  会自动驾驶,,现在我们把他们组合一下,让一个简单得汽车用这几个功能

    public class Clinet {
    
        public static void main(String[] args) {
    
            CarComponent car = new Car();
    
            System.out.println("fly swim ai auto--------------------------");
    
            DecoratorCar car2 = new WaterCar(new AICar(new FlyCar(car)));
            car2.move();
        }
    }

    就这么简单就可以了.如果不适用这样的模式的话,我们有俩种办法 1. 新建一个类 他继承 会飞 会游泳的,会自动驾驶的,或者实现一个接口 把这3个都写进行,但是这样的话不够灵活,不易扩展

    实现细节

    component: 抽象构建角色

    真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互 

    ConcreteComponent 具体构件角色(真实对象) :
    真实的对象

    Decorator装饰角色
    他持有了一个构建角色的引用,装饰对象接受对客户端的请求,并发这样请求转发给真实的对象,这样就可以在真实的对象前后实现自己的逻辑

    concreteDecorator角色

    负责给对象添加新的功能

    总结

    装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新

    的具体构建类和具体装饰类

    优点:

    1. 扩展对象比继承灵活,不会导致类个数急剧增加

    2. 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象 

    3具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类

    缺点:

     产生很多小对象,大量的小对象占据内存,一定程度上影响性能

    装饰模式出错的话,调试排查比较麻烦

    对比:

    装饰模式和桥接模式的区别

    两个模式都是为了解决过多子类对象问题。但他们的诱因不一样。桥 模式是对象自身现有机制沿着多个维度变化,是既有部分不稳定。装饰模式是为了增加新的功能

    和代理模式对比

    代理模式是在一个方法上添加将相同的操作提取出去,装饰模式是,增加新的功能

    jdk中用到的地方:

    IO流我随意找了一个地方就.大家可以看看类图

  • 相关阅读:
    nyoj592 spiral grid
    ny788 又见Alice and Bob
    hdoj 1166 敌兵布阵 线段数和树状数组
    nyoj228 士兵杀敌(5)插线问线
    nyoj576 集齐卡片赢大奖(一)
    ny269 VF
    AC Again hdoj 1582 搜索
    nyoj123 士兵杀敌(四)树状数组 插线问点
    CRAVAT: Cancer-Related Analysis of VAriants Toolkit
    第二代无创胎儿基因组分析结果
  • 原文地址:https://www.cnblogs.com/bj-xiaodao/p/10851671.html
Copyright © 2011-2022 走看看