zoukankan      html  css  js  c++  java
  • JAVA装饰者模式(从现实生活角度理解代码原理)

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

    该模式的适用环境为:

    (1)在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

    (2)处理那些可以撤消的职责。

    (3)当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

    实现该模式的关键步骤:

    (1)Component(被装饰对象基类):定义对象的接口,可以给这些对象动态增加职责;

    (2)ConcreteComponent(具体被装饰对象):定义具体的对象,Decorator可以给它增加额外的职责;

    (3)Decorator(装饰者抽象类):维护指向Component实例的引用,定义与Component一致的接口(也就是要继承或实现被装饰对象基类);

    (4)ConcreteDecorator(具体装饰者):具体的装饰对象,给内部持有的具体被装饰对象增加具体的职责;

    这样讲大家可能有些不好理解,那我们还是老规矩安静

    入冬以后天气越来越冷了,下班之后,做为资深吃货,约上二三好友痛快的来场火锅盛宴再爽不过了。说到火锅,不得不提在成都吃过的大龙燚火锅,各种锅底,配菜应有尽有,但我最喜欢的还是大龙燚火锅原味锅底、麻辣牛肉、大刀毛肚、天味香肠、砣砣牛肉、麻辣排骨等,想想都流口水啊。

    说道这大家结合装饰者的实现步骤,应该有点感觉了吧,上文提到的锅底,其实就是被装饰对象的基类,配料其实就是装饰者抽象类,大龙燚火锅原味锅底这些具体的锅底也就是具体的被装饰对象了,麻辣牛肉、大刀毛肚、天味香肠、砣砣牛肉、麻辣排骨这些装饰锅底用的各种配菜也就是具体的装饰对象说道这,大家应该都豁然开朗了吧,下面我们开始具体的代码实现:

    第一步:定义被装饰对象基类(可以是抽象类也可以是接口)

    1 public interface GuoDi {
    2     public float cost();//锅底当然要有价钱啦
    3     public String name();//名字也得有哦
    4 }

    第二步:定义具体被装饰对象(也就是各种锅底,这里定义两种)

     1 public class YuanYang implements GuoDi {
     2     @Override
     3     public float cost() {
     4         return 48.0f;
     5     }
     6     @Override
     7     public String name() {
     8         return "鸳鸯锅底";
     9     }
    10 }
    11 public class DaLongYan implements GuoDi{
    12     @Override
    13     public float cost() {
    14         return 59.0f;
    15     }
    16     @Override
    17     public String name() {
    18         return "大龙燚火锅原味锅底";
    19     }
    20 }

    第三步:定义装饰者抽象类

     1 public abstract class PeiCai implements GuoDi {
     2     private GuoDi guodi;
     3     public FoodDecorator(GuoDi guodi) {
     4         super();
     5         this.guodi = guodi;
     6     }
     7     @Override
     8     public float cost() {
     9         return guodi.cost();
    10     }
    11     @Override
    12     public String name() {
    13         return guodi.name();
    14     }
    15 }

    第四步:定义具体的装饰者对象

     1 public class MaLaNiuRou extends PeiCai {
     2     public MaLaNiuRou(GuoDi guodi) {
     3         super(guodi);
     4     }
     5     @Override
     6     public float cost() {
     7         return super.cost()+46f;
     8     }
     9     @Override
    10     public String name() {
    11         return super.name()+"+麻辣牛肉";
    12     }
    13 }
    14 public class MaoDu extends PeiCai {
    15 
    16     public MaoDu(GuoDi guodi) {
    17         super(guodi);
    18     }
    19     @Override
    20     public float cost() {
    21         return super.cost()+30f;
    22     }
    23     @Override
    24     public String name() {
    25         return super.name()+"+大刀毛肚";
    26     }
    27 }

    测试类:

    1 public class Test {
    2     public static void main(String[] args) {
    3         GuoDi  guodi = new DaLongYan ();//点个大龙燚火锅原味锅底
    4         MaLaNiuRou y = new MaLaNiuRou(guodi);//来个麻辣牛肉
    5         MaoDu  x = new MaoDu(y);//在麻辣牛肉的基础上再来个大刀毛肚
    6         System.out.println("一共点了"+x.name()+",共消费"+s.cost());
    7     }
    8 }

    输出结果:

     1 一共点了大龙燚火锅原味锅底+麻辣牛肉+大刀毛肚,共消费135 

    不知道大家这顿吃的满意不,不行的话,咱去成都来顿真正的装饰者设计模式,看我不把我的大龙燚火锅原味锅底装饰的让你走不动道羡慕

  • 相关阅读:
    Brocade FC Switch 光信号强度查看
    [Err]1418 This function has none of DETERMINISTIC,NO SQL,or R
    VBA 新手疑难杂症记录(不断更新中…)
    VBA 学习之旅(一) —— 数据类型
    ELO等级分制度
    Grunt上手指南<转>
    新开始新挑战
    html5大纲算法(目录树)
    隐居网V2.0
    长焦点图的解决方案(全兼容)
  • 原文地址:https://www.cnblogs.com/panhouye/p/6120232.html
Copyright © 2011-2022 走看看