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

    四种角色

    抽象构件(一个类):被装饰的抽象类

    具体构件(可以多个类):要被装饰的

    装饰类(一个类):它并不知道要装饰哪个具体构件,所以需要做装饰工作的时候接受外边传过来的具体构件对象,故在内部需要一个抽象构件接口类来接受具体的构件对象。

    具体装饰(可以多个类):装饰品

    对于装饰类和具体装饰类来说: 在构造函数中,将要装饰的具体构件对象传参数进去,定义构造函数的时候,参数写抽象构造接口的声明。

    装饰类可以是抽象类,他是具体装饰类的父类

    装饰类要继承抽象构件类



    装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。

    在装饰模式中的角色有:

      ●  抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。

      ●  具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。

      ●  抽象装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。

      ●  具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

    源代码

      抽象构件角色

    public interface Component {
        
        public void sampleOperation();
        
    }

      具体构件角色

    复制代码
    public class ConcreteComponent implements Component {
    
        @Override
        public void sampleOperation() {
            // 写相关的业务代码
        }
    
    }
    复制代码

      装饰角色

    复制代码
    public class Decorator implements Component{
        private Component component;
        
        public Decorator(Component component){
            this.component = component;
        }
    
        @Override
        public void sampleOperation() {
            // 委派给构件
            component.sampleOperation();
        }
        
    }
    复制代码

      具体装饰角色

    复制代码
    public class ConcreteDecoratorA extends Decorator {
    
        public ConcreteDecoratorA(Component component) {
            super(component);
        }
        
        @Override
        public void sampleOperation() {
         super.sampleOperation();
    // 写相关的业务代码 } }
    复制代码
    复制代码
    public class ConcreteDecoratorB extends Decorator {
    
        public ConcreteDecoratorB(Component component) {
            super(component);
        }
        
        @Override
        public void sampleOperation() {
         super.sampleOperation();
    // 写相关的业务代码 } }
    复制代码





    装饰者模式

    动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

    具体被装饰者和抽象装饰类都继承于抽象被装饰者类,继承的是类型,而不是行为。行为来自装饰者和基础组件,或与其他装饰者之间的组合关系。

    装饰者通常是用其他类似于工厂或生成器这样的模式创建的。

        

           具体例子

    抽象被继承者类:Beverage.java

    //抽象构件类

    [java] view plaincopy
    1. package com.designpattern.decorator;  
    2.   
    3. //被装饰者抽象类  
    4. public abstract class Beverage {  
    5.     String description = "Unknown Beverage";  
    6.       
    7.     public String getDescription(){  
    8.         return description;  
    9.     }  
    10.       
    11.     public abstract double cost();  
    12. }  

    具体被装饰类:HouseBlend.java, DarkRoast.java, Decat.java, Espresso.java,只给出一个,其他类似

    //具体构件类

    [java] view plaincopy
    1. package com.designpattern.decorator;  
    2.   
    3. //被装饰者具体类  
    4. public class HouseBlend extends Beverage{  
    5.   
    6.     public HouseBlend(){  
    7.         description = "House Blend Coffee";  
    8.     }  
    9.       
    10.     @Override  
    11.     public double cost() {  
    12.         // TODO Auto-generated method stub  
    13.         return 0.89;  
    14.     }  
    15.   
    16. }  

    装饰者抽象类:CondimentDecorator.java

    //抽象装饰类

    [java] view plaincopy
    1. package com.designpattern.decorator;  
    2.   
    3. //装饰者抽象类  
    4. public abstract class CondimentDecorator extends Beverage{  
    5.     public abstract String getDescription();  
    6. }  

    具体装饰者类:Mocha.java,Soy.java,Milk.java,Whip.java,只给出一个,其他类似

    //具体装饰类

    [java] view plaincopy
    1. package com.designpattern.decorator;  
    2.   
    3. //装饰者的具体类  
    4. public class Mocha extends CondimentDecorator{  
    5.     Beverage beverage;  
    6.       
    7.     public Mocha(Beverage beverage){  
    8.         this.beverage = beverage;  
    9.     }  
    10.   
    11.     @Override  
    12.     public String getDescription() {  
    13.         // TODO Auto-generated method stub  
    14.         return beverage.getDescription() + ", Mocha";  
    15.     }  
    16.   
    17.     @Override  
    18.     public double cost() {  
    19.         // TODO Auto-generated method stub  
    20.         return 0.20 + beverage.cost();  
    21.     }  
    22.   
    23. }  


    测试类:Test.java

    [java] view plaincopy
    1. package com.designpattern.decorator;  
    2.   
    3. public class Test {  
    4.     public static void main(String[] args) {  
    5.         //不需要调料,即没有装饰者  
    6.         Beverage beverage1 = new Espresso();  
    7.         System.out.println(beverage1.getDescription() + " $" + beverage1.cost());  
    8.           
    9.         //使用了三个装饰者来装饰DarkRoast  
    10.         Beverage beverage2 = new DarkRoast();  
    11.         beverage2 = new Mocha(beverage2);  

    12. //在装饰beverage2,

    13.  因为Mocha的父类的父类是Beverage,故装

    14. 饰完了之后,赋值给Beverage的引用
    15.         beverage2 = new Soy(beverage2);  
    16.         beverage2 = new Whip(beverage2);  
    17.         System.out.println(beverage2.getDescription() + " $" + beverage2.cost());  
    18.           
    19.         //使用了两个装饰者来装饰HouseBlend  
    20.         Beverage beverage3 = new HouseBlend();  
    21.         beverage3 = new Mocha(beverage3);  
    22.         beverage3 = new Soy(beverage3);  
    23.         System.out.println(beverage3.getDescription() + " $" + beverage3.cost());  
    24.           
    25.     }  
    26. }  

             要点总结

    1)继承属于扩展形式之一,但不见得是达到弹性设计的最佳方式。

    2)在设计中,应该允许行为可以被扩展,而无须修改现有的代码。

    3)组合和委托可用于在运行时动态地加上新的行为。

    4)除了继承,装饰者模式也可以让我们扩展行为。

    5)装饰者模式意味着一群装饰者类,这些类用来包装具体组件。

    6)装饰者类反映出被装饰的组件类型(事实上,他们具有相同的类型,都经过接口或继承实现)。

    7)装饰者可以在被装饰者的行为前面与/或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的目的。

    8)可以用无数个装饰者包装一个组件。

    9)装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。

    10)装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。






  • 相关阅读:
    HTML5全屏API在FireFox/Chrome中的显示差异(转)
    过程需要参数 '@statement' 为 'ntext/nchar/nvarchar'
    程序员面试zhongdian
    select into #T from ,insert into #T select ,insert into #T exec
    Log4Net Layout使用以及扩展
    jdbc报java.lang.ClassNotFoundException: com.mysql.jdbc.Drive
    eclipse的maven项目中找不到Maven Dependencies
    elfinder中通过DirectoryStream.Filter实现筛选隐藏目录(二)
    一个好用的字符过滤,差异匹配补丁的扩展库,各语言版本
    java调用c/c++代码简单实现以及遇见的坑
  • 原文地址:https://www.cnblogs.com/baoendemao/p/3804770.html
Copyright © 2011-2022 走看看