• 一、装饰者模式


    一、先看大神笔记

    https://www.cnblogs.com/of-fanruice/p/11565679.html

    二、定义

    装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

    三、装饰者模式的构成

    1.抽象组件:需要装饰的抽象对象(接口或抽象父类)

    2.具体组件:需要装饰的对象

    3.抽象装饰类:包含了对抽象组件的引用以及装饰共有的方法

    4.具体装饰类:被装饰的对象

    四、适用性

    以下情况使用Decorator模式
    1. 需要扩展一个类的功能,或给一个类添加附加职责。
    2. 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
    3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
    4. 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

    五、优点

    1. Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
    2. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

    六、缺点

    1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
    2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
    3. 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

    七、实际使用

    java IO 流是典型的装饰模式。

     八、模拟咖啡

     1 package com.io;
     2 /**
     3  * 模拟咖啡
     4  * 1、抽象组件:需要装饰的抽象对象(接口或抽象父类)
     5  * 2、具体组件:需要装饰的对象
     6  * 3、抽象装饰类:包含了对抽象组件的引用以及装饰着共有的方法
     7  * 4、具体装饰类:被装饰的对象
     8  *
     9  *
    10  */
    11 public class Test1 {
    12     public static void main(String[] args) {
    13         Drink coffee = new Coffee();
    14         System.out.println(coffee.cost());    //10
    15         System.out.println(coffee.info());    //"原味咖啡"
    16         Drink suger = new Suger(coffee);    //装饰
    17         System.out.println(suger.info()+"-->"+suger.cost());
    18         Drink milk = new Milk(coffee);     //装饰
    19         System.out.println(milk.info()+"-->"+milk.cost());
    20         Drink max = new Milk(suger);
    21         System.out.println(max.info()+"-->"+max.cost());
    22     }
    23 }
    24 
    25 //抽象组件
    26 interface Drink{
    27     double cost();  //费用
    28     String info();  //说明
    29 }
    30 
    31 //具体组件
    32 class Coffee implements  Drink{
    33     private  String name = "原味咖啡";
    34     @Override
    35     public double cost() {
    36         return 10;
    37     }
    38 
    39     @Override
    40     public String info() {
    41         return name;
    42     }
    43 }
    44 
    45 //抽象装饰类
    46 abstract class  Decorate implements Drink{
    47     //对抽象组件的引用
    48     private Drink drink;
    49     public Decorate(Drink drink){
    50         this.drink = drink;
    51     }
    52     @Override
    53     public double cost() {
    54         return this.drink.cost();
    55     }
    56 
    57     @Override
    58     public String info() {
    59         return this.drink.info();
    60     }
    61 }
    62 
    63 //具体装饰类
    64 class  Milk extends  Decorate{
    65     public  Milk(Drink drink){
    66         super(drink);
    67     }
    68 
    69     @Override
    70     public double cost() {
    71         return super.cost()*4;
    72     }
    73 
    74     @Override
    75     public String info() {
    76         return super.info()+"加入了牛奶";
    77     }
    78 }
    79 
    80 //具体抽象类
    81 class Suger extends Decorate{
    82     public Suger(Drink drink){
    83         super(drink);
    84     }
    85 
    86     @Override
    87     public double cost() {
    88         return super.cost()*2;
    89     }
    90 
    91     @Override
    92     public String info() {
    93         return super.info()+"加入了蔗糖";
    94     }
    95 }

  • 相关阅读:
    如何使用API创建OpenStack虚拟机?
    Windows Server 2012 新特性:IPAM的配置
    DNSSec
    Win Server 8中的利器:微软在线备份服务
    AD RMS总结
    开发中辅助功能
    开发中坑爹的地方
    Js 中常用方法
    asp.net 错误处理
    js中的注意事项(持续整理)
  • 原文地址:https://www.cnblogs.com/qiaoxin11/p/12598457.html
Copyright © 2020-2023  润新知