• java中的装饰设计模式,浅谈与继承之间的区别


    最初接触装饰设计模式,一直搞不懂这么做的意义是什么,看了网上很多的资料,对于与继承的区别并没有很清楚的分析,直到看到这篇博客:http://www.cnblogs.com/rookieFly-tdiitd/p/4914593.html 这篇就很清楚的解释了装饰设计模式与继承之间的区别。下面是我自己的一些理解。

    一、概念

    装饰模式又称为包装模式,动态地给对象添加功能,是继承关系的一种替代方法。

    二、选择

    子类通过继承也能增加功能,但是关于装饰模式与继承之间如何选择,请看下面的例子。

    假设:煎饼是父类,成员变量是money,也可以在煎饼上添加火腿、辣条、土豆丝、鸡蛋。如果使用子类继承父类的方式,那么要吃这么一个煎饼可能会出现多少种情况呢?

    这里我们看到如果使用子类继承父类,那么我们要写很多子类,这么做无疑增加了程序的臃肿性,并不是很灵活。这时,装饰模式就诞生了。

    三、格式

    首先我们要有一个真实的对象装饰对象,它们两个要实现同一个接口,还有有具体的装饰对象,简易的说就是将真实对象作为具体装饰对象的构造方法的参数,给装饰对象添加功能。

     四、代码

    接口类:

    1 package Decorate;
    2 
    3 public interface Jianbing {
    4     //获取价格
    5     public float getMoney();
    6     //返回煎饼的信息
    7     public String description();
    8 }

    抽象装饰类:

     1 package Decorate;
     2 //装饰的对象
     3 public abstract class DecorateJianbing implements Jianbing {
     4     private Jianbing jianbing;
     5     
     6     public DecorateJianbing(Jianbing jianbing) {
     7         super();
     8         this.jianbing = jianbing;
     9     }
    10 
    11     @Override
    12     public float getMoney() {
    13 
    14         return jianbing.getMoney();
    15     }
    16 
    17     @Override
    18     public String description() {
    19 
    20         return jianbing.description();
    21     }
    22 
    23 }

    真实对象

     1 package Decorate;
     2 //真实的对象
     3 public class TrueJianbing implements Jianbing {
     4 
     5     @Override
     6     public float getMoney() {
     7 
     8         return 3f;
     9     }
    10 
    11     @Override
    12     public String description() {
    13 
    14         return "煎饼";
    15     }
    16 
    17 }

    抽象装饰类的具体类:

     1 package Decorate;
     2 
     3 public class Egg extends DecorateJianbing {
     4 
     5     public Egg(Jianbing jianbing) {
     6         super(jianbing);
     7         // TODO Auto-generated constructor stub
     8     }
     9 
    10     @Override
    11     public float getMoney() {
    12         
    13         return super.getMoney()+ 1f;
    14     }
    15 
    16     @Override
    17     public String description() {
    18         
    19         return super.description() + "+鸡蛋";
    20     }
    21     
    22 }
     1 package Decorate;
     2 
     3 public class Huotui extends DecorateJianbing {
     4 
     5     public Huotui(Jianbing jianbing) {
     6         super(jianbing);
     7         // TODO Auto-generated constructor stub
     8     }
     9 
    10     @Override
    11     public float getMoney() {
    12         
    13         return super.getMoney()+1f;
    14     }
    15 
    16     @Override
    17     public String description() {
    18         
    19         return super.description()+"+火腿肠";
    20     }
    21     
    22 }
     1 package Decorate;
     2 
     3 public class Latiao extends DecorateJianbing {
     4 
     5     public Latiao(Jianbing jianbing) {
     6         super(jianbing);
     7         // TODO Auto-generated constructor stub
     8     }
     9 
    10     @Override
    11     public float getMoney() {
    12         
    13         return super.getMoney()+0.5f;
    14     }
    15 
    16     @Override
    17     public String description() {
    18         
    19         return super.description()+"+辣条";
    20     }
    21     
    22 }
     1 package Decorate;
     2 
     3 public class Tudousi extends DecorateJianbing {
     4 
     5     public Tudousi(Jianbing jianbing) {
     6         super(jianbing);
     7         // TODO Auto-generated constructor stub
     8     }
     9 
    10     @Override
    11     public float getMoney() {
    12         
    13         return super.getMoney()+0.5f;
    14     }
    15 
    16     @Override
    17     public String description() {
    18         
    19         return super.description()+"+土豆丝";
    20     }
    21     
    22 }

    测试类:

     1 public class DemoTest {
     2     //这里可以任意组合,当然要把所有的组合,就要把这些一个个叠加上,就像最后一个例子
     3     public static void main(String[] args) {
     4         //无任何添加的煎饼
     5         TrueJianbing tjb = new TrueJianbing();
     6         
     7         //加鸡蛋的煎饼
     8         Egg egg = new Egg(tjb);
     9         System.out.println(egg.description()+" 价格:"+egg.getMoney());
    10         
    11         //加辣条的煎饼
    12         Latiao lt = new Latiao(tjb);
    13         System.out.println(lt.description()+" 价格:"+lt.getMoney());
    14         
    15         //加鸡蛋 辣条 土豆丝 火腿肠
    16         Tudousi tudousi = new Tudousi(lt);
    17         Huotui huotui = new Huotui(tudousi);
    18         egg = new Egg(huotui);
    19         System.out.println(egg.description()+" 价格:"+egg.getMoney());
    20         
    21     }
    22 
    23 }

    打印:

    煎饼+鸡蛋 价格:4.0
    煎饼+辣条 价格:3.5
    煎饼+辣条+土豆丝+火腿肠+鸡蛋 价格:6.0

    我们可以将装饰的具体类任意组合,这样是不是比刚开始介绍的继承方法好多了呢?

    那么我们就总结一下装饰模式有什么特点。

    优点:

    --装饰模式降低了类与类之间的耦合度,可以动态地增加或删除功能,装饰类及具体装饰类可以独立地进行变化,以便后期增加或者删除类。

    --扩展对象功能,比继承要灵活,不会导致类的个数急剧地增加。

    缺点:

    --产生很多的小对象,大量的小对象会占用内存。

    --组合方式很多,很容易出错。

  • 相关阅读:
    Eclipse中支持js提示
    数据库命名规则
    JavaWeb 命名规则
    Ajax&json
    js中,var 修饰变量名和不修饰的区别
    javaScript知识点
    Bootstrap 栅格系统
    文本框如果不输入任何内容提交过后是一个空字符串还是null
    根据汇总数量依次扣减的SQL新语法
    asp.net中使用forms验证
  • 原文地址:https://www.cnblogs.com/losedMemory/p/6246029.html
Copyright © 2020-2023  润新知