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

一、概念

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

二、选择

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

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

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

三、格式

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

四、代码

接口类:

 package Decorate;

 public interface Jianbing {
//获取价格
public float getMoney();
//返回煎饼的信息
public String description();
}

抽象装饰类:

 package Decorate;
//装饰的对象
public abstract class DecorateJianbing implements Jianbing {
private Jianbing jianbing; public DecorateJianbing(Jianbing jianbing) {
super();
this.jianbing = jianbing;
} @Override
public float getMoney() { return jianbing.getMoney();
} @Override
public String description() { return jianbing.description();
} }

真实对象

 package Decorate;
//真实的对象
public class TrueJianbing implements Jianbing { @Override
public float getMoney() { return 3f;
} @Override
public String description() { return "煎饼";
} }

抽象装饰类的具体类:

 package Decorate;

 public class Egg extends DecorateJianbing {

     public Egg(Jianbing jianbing) {
super(jianbing);
// TODO Auto-generated constructor stub
} @Override
public float getMoney() { return super.getMoney()+ 1f;
} @Override
public String description() { return super.description() + "+鸡蛋";
} }
 package Decorate;

 public class Huotui extends DecorateJianbing {

     public Huotui(Jianbing jianbing) {
super(jianbing);
// TODO Auto-generated constructor stub
} @Override
public float getMoney() { return super.getMoney()+1f;
} @Override
public String description() { return super.description()+"+火腿肠";
} }
 package Decorate;

 public class Latiao extends DecorateJianbing {

     public Latiao(Jianbing jianbing) {
super(jianbing);
// TODO Auto-generated constructor stub
} @Override
public float getMoney() { return super.getMoney()+0.5f;
} @Override
public String description() { return super.description()+"+辣条";
} }
 package Decorate;

 public class Tudousi extends DecorateJianbing {

     public Tudousi(Jianbing jianbing) {
super(jianbing);
// TODO Auto-generated constructor stub
} @Override
public float getMoney() { return super.getMoney()+0.5f;
} @Override
public String description() { return super.description()+"+土豆丝";
} }

测试类:

 public class DemoTest {
//这里可以任意组合,当然要把所有的组合,就要把这些一个个叠加上,就像最后一个例子
public static void main(String[] args) {
//无任何添加的煎饼
TrueJianbing tjb = new TrueJianbing(); //加鸡蛋的煎饼
Egg egg = new Egg(tjb);
System.out.println(egg.description()+" 价格:"+egg.getMoney()); //加辣条的煎饼
Latiao lt = new Latiao(tjb);
System.out.println(lt.description()+" 价格:"+lt.getMoney()); //加鸡蛋 辣条 土豆丝 火腿肠
Tudousi tudousi = new Tudousi(lt);
Huotui huotui = new Huotui(tudousi);
egg = new Egg(huotui);
System.out.println(egg.description()+" 价格:"+egg.getMoney()); } }

打印:

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

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

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

优点:

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

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

缺点:

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

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

java中的装饰设计模式,浅谈与继承之间的区别的更多相关文章

  1. 对kotlin和java中的synchronized的浅谈

    synchronized在java中是一个关键字,但是在kotlin中是一个内联函数.假如分别在java和kotlin代码锁住同一个对象,会发生什么呢,今天写了代码试了试.首先定义people类 12 ...

  2. Java中Integer和String浅谈

    Java中的基本数据类型有八种:int.char.boolean.byte.long.double.float.short.Java作为一种面向对象的编程语言,数据在Java中也是一种对象.我们用基本 ...

  3. Java中常用修饰符浅谈

    一.public.protected.default和private修饰符的作用域 public:在java程序中,如果将属性和方法定义为 public 类型,那么此属性和方法所在的类和及其子类,同一 ...

  4. Java中的SPI原理浅谈

    在面向对象的程序设计中,模块之间交互采用接口编程,通常情况下调用方不需要知道被调用方的内部实现细节,因为一旦涉及到了具体实现,如果需要换一种实现就需要修改代码,这违反了程序设计的"开闭原则& ...

  5. Java中的容器 I————浅谈Queue和PriorityQueue

    一.Queue的实现 通过LinkedList类实现Queue接口来完成对Queue的实例类的实现,代码如下: Queue<Integer> queue=new LinkedList< ...

  6. Java中的容器 I————浅谈List

    一.List接口的继承关系 List接口是Collection接口的子接口,而ArrayList和LinkedList以及Vector是其实现类. List的特点是可以将元素维护在特定的序列中,可以再 ...

  7. 谈谈Java中的集合list、set、map之间的区别

    参考文献:https://www.cnblogs.com/IvesHe/p/6108933.html 我这里只总结其区别,具体的说明,请查看参考文献,讲的很详细. A.list接口,实现子类有:arr ...

  8. 浅谈cookie 和session 的区别

    具体来说 cookie 是保存在“客户端”的,而session是保存在“服务端”的 cookie 是通过扩展http协议实现的 cookie 主要包括 :名字,值,过期时间,路径和域: 如果cooki ...

  9. Java基础-Java中23种设计模式之常用的设计模式

    Java基础-Java中23种设计模式之常用的设计模式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.设计模式分类 设计模式是针对特定场景给出的专家级的解决方案.总的来说设 ...

随机推荐

  1. mvc 母版页、用户自定义控件

    母版页(Master) 1.母版页是与Controller无关的,母版页只是一个View文件,而没有任何Controller与之相对应. 2.其实在ASP.NET MVC中View的aspx与母版页并 ...

  2. linux中php配置

    安装nginx+php好久了,今天意外的搭建好了,分享给大家 ,以免以后多走弯路. nginx已经前面安装好了,现在就开始配置php 安装php 分为两个部分 :一部分是php源码,另外是fastcg ...

  3. Immutable 详解及 React 中实践

    本文转自:https://github.com/camsong/blog/issues/3 Shared mutable state is the root of all evil(共享的可变状态是万 ...

  4. Androidndk开发打包时我们应该如何注意平台的兼容(x86,arm,arm-v7a)

    很多朋友在开发Android JNI的的时候,会遇到findlibrary returned null的错误,因为某种原因,so没有打包到apk中.下面浅析下引起该错误的原因以及平台兼容性问题. 一. ...

  5. POJ 1067 取石子游戏 威佐夫博弈

    威佐夫博弈(Wythoff Game):有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜. 我们用(ak,bk)(ak ≤ bk ,k= ...

  6. Block 实现 浅析

    前言 这里 有关于 block 的 5 道测试题,建议你阅读本文之前先做一下测试. 先介绍一下什么是闭包.在 wikipedia 上,闭包的定义) 是: In programming language ...

  7. iOS 2.0 版本切入点

    转载自:http://www.infoq.com/cn/articles/Version_2_0 移动互联网如火如荼,iOS 应用+ Android 应用+ 手机站似乎成了所有互联网公司的标配,你的网 ...

  8. iOS 6 Passbook 入门 1/2

    http://www.raywenderlich.com/zh-hans/23066/ios-6-passbook-%E5%85%A5%E9%97%A8-12 iOS 6 Passbook 入门 1/ ...

  9. android Actionmode 样式自定义

    <style name="Base.Theme.DesignDemo" parent="Theme.AppCompat.Light.NoActionBar" ...

  10. lucene中Field.Index,Field.Store的一些设置

    lucene在doc.add(new Field("content",curArt.getContent(),Field.Store.NO,Field.Index.TOKENIZE ...