[23种设计模式]---装饰者模式(1)

装饰者官方说:

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

咱这么说:

  比如说,我要设计一个咖啡厅订单管理项目, 订单肯定包括 咖啡的种类和一些配料,如果我设计一个抽象类,让所有这些东西都去继承他,那肯定会引起类爆炸,自己以后想往里添加新的咖啡类型和配料,你都有可能找不到,影响拓展性,不方便改动和维护,就行这样,多麻烦, 

第二种优化是咖啡我一定要但是配料,像什么牛奶冰块,巧克力我可以选择不要,就喝咖啡,这时我们就想到,把配料变成boolean类型,如果是0了我代表我不要,1代表我要,但是这么做有一点不好,有的顾客说,老板 ! 加两份牛奶,一份冰,这是就不可以了

装饰者模式来了!

  这么说吧,装饰者模式就像打包一个快递,把你想要的东西一层一层的包进去,就像俄罗斯套娃一样,要什么就往里放,邮走之后,在那边打开的时候,就用递归的方式,一层一层给它拆开,

  比如说,老板!我要一个无糖咖啡,一份奶,两份冰,安排一下!

程序代码:

饮品定义为抽象类,定义商品和价格,有一个抽象方法cost(),记录总花费

 1 package learn.Decorate.Decorate_L;
 2
 3 public abstract class Drink {
 4     public String decoration="";
 5     private float price;
 6
 7     public String getDecoration() {
 8         return decoration+"-"+this.price;
 9     }
10
11     public void setDecoration(String decoration) {
12         this.decoration = decoration;
13     }
14
15     public float getPrice() {
16         return price;
17     }
18
19     public void setPrice(float price) {
20         this.price = price;
21     }
22     public abstract float cost();
23 }

我们创建俩个类(Decorator和Coffee)分别继承Drink类,为什么这么麻烦呢,因为你会点一份咖啡配上多个配料(牛奶,冰),不会点两个咖啡,要一份配料,这里的两个类分别代表主品咖啡和配料.

1 package learn.Decorate.Decorate_L;
2
3 public class Coffee extends Drink {
4     @Override
5     public float cost() {
6         return super.getPrice();
7     }
8 }
 1 package learn.Decorate.Decorate_L;
 2 //注意这里,它是一层一层往里包裹的,
 3 public class Decorator extends Drink {
 4     private Drink obj;
 5
 6     public Decorator(Drink obj) {
 7         this.obj = obj;
 8     }
 9
10     @Override
11     public float cost() {
12         return super.getPrice()+obj.cost();
13     }
14
15     public String getDecoration(){
16         return super.getDecoration()+"&&"+obj.getDecoration();
17     }
18 }

无糖咖啡来了!

1 package learn.Decorate.Decorate_L;
2
3 public class Delcoff extends Coffee {
4     public Delcoff() {
5         super.setDecoration("Delcoff无糖咖啡");
6         super.setPrice(12.5f);
7     }
8 }

ShortBlack咖啡来了

1 package learn.Decorate.Decorate_L;
2
3 public class ShortBlack extends Coffee {
4     public ShortBlack() {
5         super.setDecoration("ShortBlack咖啡");
6         super.setPrice(14.5f);
7     }
8 }

冰块,它来了,它来了!

1 package learn.Decorate.Decorate_L;
2
3 public class Ice extends Decorator {
4     public Ice(Drink obj) {
5         super(obj);
6         super.setDecoration("加冰");
7         super.setPrice(0.8f);
8     }
9 }

牛的奶,嘎嘎纯的牛奶来了!

1 package learn.Decorate.Decorate_L;
2
3 public class Mike extends Decorator {
4     public Mike(Drink obj) {
5         super(obj);
6         super.setDecoration("加奶");
7         super.setPrice(3.2f);
8     }
9 }

开始点菜,老板!我要一份ShortBlack咖啡,再给我旁边不认识的小姐姐来一份无糖咖啡,加一份奶,两份冰.

 1 package learn.Decorate.Decorate_L;
 2
 3 public class CoffeeTest {
 4     public static void main(String[] args) {
 5         Drink order;
 6         order = new ShortBlack();
 7         System.out.println("订单1包括:"+order.getDecoration());
 8         System.out.println("总价:"+order.cost());
 9         System.out.println("----------------------");
10
11         order = new Delcoff();
12         order = new Mike(order);
13         order = new Ice(order);
14         order = new Ice(order);
15         System.out.println("订单2包括:"+order.getDecoration());
16         System.out.println("总价:"+order.cost());
17     }
18 }

没毛病出来跑两圈,!!!

1 订单1包括:ShortBlack咖啡-14.5
2 总价:14.5
3 ----------------------
4 订单2包括:加冰-0.8&&加冰-0.8&&加奶-3.2&&Delcoff无糖咖啡-12.5
5 总价:17.3
6
7 Process finished with exit code 0

拓展一下,无意中我发现IO的工作原理也是这样,被来要把源码都扒下来分析一下的,刚才接到一个面试电话让我下午面试,就不说了,放张图,有兴趣的自己研究一下,我放一个调用内置的装饰者模式的简单项目吧,就是把你txt文件中的大小写变成大写

 1 package learn.Decorate.UpperCaseInputStream;
 2
 3 import java.io.FilterInputStream;
 4 import java.io.IOException;
 5 import java.io.InputStream;
 6
 7 public class UpperCaseInputStream extends FilterInputStream {
 8     /**
 9      * Creates a <code>FilterInputStream</code>
10      * by assigning the  argument <code>in</code>
11      * to the field <code>this.in</code> so as
12      * to remember it for later use.
13      *
14      * @param in the underlying input stream, or <code>null</code> if
15      *           this instance is to be created without an underlying stream.
16      */
17     protected UpperCaseInputStream(InputStream in) {
18         super(in);
19     }
20
21     public int read() throws IOException {
22         int c = super.read();
23         return c == -1 ? c : Character.toUpperCase((char) (c));
24     }
25
26
33 }

在桌面上自己建立一个huang.txt,里面英文随便打,有小写可以,大小写混合也可以,全大写,那你就左走右走把

 1 package learn.Decorate.UpperCaseInputStream;
 2
 3 import java.io.*;
 4
 5 public class InputTest {
 6     public static void main(String[] args) {
 7         int c;
 8         try {
 9             InputStream in = new UpperCaseInputStream(new BufferedInputStream(new FileInputStream("C:\\Users\\Jerry\\Desktop\\huang.txt")));
10             while ((c = in.read())>=0){
11                 System.out.print((char)c);
12             }
13         }  catch (IOException e) {
14             e.printStackTrace();
15         }
16     }
17 }

运行一下:

1 THIS IS A BOOK
2 Process finished with exit code 0

ok 没问题! 今天就到这了,下课!

如有错误一定要联系我更改,初出茅庐,有些不懂请见谅!

  

原文地址:https://www.cnblogs.com/laotiebuhuang/p/11194015.html

时间: 2024-07-29 04:55:07

[23种设计模式]---装饰者模式(1)的相关文章

Java经典23种设计模式之创造型模式(二)

本文记录5种创造型模式的剩下两种:建造者模式(Builder).原型模式(PROTOTYPE). 一.建造者模式(别名:生成者模式) 将复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示.一个完整的建造者模式包含以下几个概念: 1.产品类 Product public class Person { private String head; private String body; private String foot; public String getHead() { ret

JAVA开发的23种设计模式之 --- 桥接模式

桥接模式 概述:将抽象部分与他的实现部分分离,这样抽象化与实现化解耦,使他们可以独立的变化.如何实现解耦的呢,就是通过提供抽象化和实现化之间的桥接结构.    应用场景        实现系统可能有多个角度分类,每一种角度都可能变化.    解释:桥接模式将继承模式转化成关联关系,他降低了类与类之间的耦合度,减少了系统中类的数量,也减少了代码量.    理解抽象化,实现化,解耦        抽象化:将复杂物体的一个或几个共同的特性抽出去而只注意其他特性的行动或过程.在java面向对象中抽象化就

Java经典23种设计模式之创造型模式(一)

设计模式被称为程序猿的内功,之前零零散散的看过一大部分,但自己么有总结过.故此次在这里总结下.值得一提的是,设计模式并不是Java所特有.由于一直搞Android.这里就用Java为载体.最经典的设计模式有23种,分三个大类型: 创建型模式(5) .结构型模式(7).行为型模式(11),5 + 7 +11 = 23.网上一搜也都是一大把了,这里不过个人作的记录.本文记录创造型模式里的工厂方法(Factory Method).抽象工厂(Abstract Factory).单例模式这三种.力求透彻.

23种设计模式(19)---Command模式

命令(Command)模式属于对象的行为模式[GOF95].命令模式又称为行动(Action)模式或交易(Transaction)模式.命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能. 命令模式是对命令的封装.命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象. 每一个命令都是一个操作:请求的一方发出请求要求执行一个操作:接收的一方收到请求,并执行操作.命令模式允许请求的一方和接收的

java实现23种设计模式之代理模式

看代码: package com.ceshi7; public interface Sourceable { public void method(); } package com.ceshi7; public class Source implements Sourceable{ @Override public void method() { System.out.println("这是原方法!"); } } package com.ceshi7; public class Pro

23种设计模式之代理模式(Proxy)

代理模式是一种对象结构型模式,可为某个对象提供一个代理,并由代理对象控制对原对象的引用.代理模式能够协调调用者和被调用者,能够在一定程度上降低系统的耦合度,其缺点是请求的处理速度会变慢,并且实现代理模式需要额外的工作. 优点: 1)远程代理可以隐藏对象位于不同的地址空间的事实. 2)虚拟代理可以执行优化操作,例如根据需要创建一个对象. 使用场景:需要比简单的指针更灵活.更全面的对象引用. Proxy 模式

23种设计模式之原型模式(Prototype)

在系统开发过程中,有时候有些对象需要被频繁创建,原型模式通过给出一个原型对象来指明所要创建的对象的类型,然后通过复制这个原型对象的办法,创建出更多同类型的对象.原型模式是一种对象创建型模式,用原型实例制定创建对象的种类,并且通过复制这些原型创建新的对象.原型模式又可分为两种:浅克隆和深克隆.浅克隆仅仅复制所考虑的对象,而不复制它所引用的对象,也就是其中的成员对象并不复制:深克隆除了对象本身被复制外,对象包含的引用也被复制,即成员对象也被复制. 优点: 1)可以在运行时添加或删除产品. 2)通过改

23种设计模式(6)--Bridge模式

面向对象的设计原则:高内聚.低耦合 软件重构原则:小步快跑------抽取的思想(抽取函数.抽取类.抽取接口):对扩展开放.对修改封闭 设计模式分类如下: Bridge模式主要是解决多维度问题,什么意思呢?类似于n*m这个公式,n种抽象的接口,m种具体的实现,最多可以有n*m种组合方式. 下面这篇文章对Bridge模式讲解的通俗易懂,于是转了过来. 学习设计模式也有一段时间了,今天就把我整理的一篇课程和大家分享,有不妥之处欢迎指出. 生活中的一个例子: 就拿汽车在路上行驶的来说.即有小汽车又有公

【Unity与23种设计模式】解释器模式(Interpreter)

GoF中定义: "定义一个程序设计语言所需要的语句,并提供解释来解析(执行)该语言." 传统上,执行程序代码通常通过两种方式 第一种:编译程序 第二种:解释器 常见的使用解释器的程序设计语言 包含流行与网页设计领域中的脚本语言 如JavaScript.PHP.Ruby等 这些程序代码经过一般文本编辑器编写完成后放入指定的位置 就可以由应用程序中的解释器直接执行 包括Lua Unity中 编写好的脚本程序执行之前会被UnityEngine编译过 严格来说不算是解释器模式 但与十几年前的开