Java设计模式学习笔记:装饰器模式

编程入门 行业动态 更新时间:2024-10-24 10:18:57

Java设计<a href=https://www.elefans.com/category/jswz/34/1771241.html style=模式学习笔记:装饰器模式"/>

Java设计模式学习笔记:装饰器模式

装饰器模式其实比较常见,大家在开发过程中其实经常用到,只不过自己还没发觉自己用到了装饰器这种设计模式,下面通过一个生活中的例子来介绍装饰器模式。

那煎饼果子来说,我们知道煎饼果子有各种配置,加鸡蛋加香肠加生菜加肉等各种豪华配置(bgm:哟哟,切克闹,煎饼果子来一套,我说鸡蛋你说要),我们用代码来体现:

首先是普通的煎饼,不做任何升级的那种,假设5块钱一个:

package com.rq.pattern.decorator.v1;/*** Title: Pancakes* Description: 普通煎饼* @author RQ * @date 2020年4月12日*/
public class Pancakes {public String getMsg() {return "普通煎饼";}public int getPrice() {return 5;}}

今天想犒劳下自己,加个鸡蛋,那就写一个加一个鸡蛋的煎饼,鸡蛋1块钱:

package com.rq.pattern.decorator.v1;/*** Title: Pancakes* Description: 加了一个鸡蛋的煎饼* @author RQ * @date 2020年4月12日*/
public class PancakesWithEgg extends Pancakes{public String getMsg() {return super.getMsg()+"+1个鸡蛋";}public int getPrice() {return super.getPrice()+1;}}

如果还想再膨胀一下,再加根香肠,那就写一个加一个鸡蛋一根香肠的煎饼,鸡蛋2块钱:

package com.rq.pattern.decorator.v1;/*** Title: Pancakes* Description: 加了一个鸡蛋和香肠的煎饼* @author RQ * @date 2020年4月12日*/
public class PancakesWithEggAndSausage extends PancakesWithEgg{public String getMsg() {return super.getMsg()+"+1根香肠";}public int getPrice() {return super.getPrice()+2;}}

运行看一下:

package com.rq.pattern.decorator;import com.rq.pattern.decorator.v1.Pancakes;
import com.rq.pattern.decorator.v1.PancakesWithEgg;
import com.rq.pattern.decorator.v1.PancakesWithEggAndSausage;public class TestV1 {public static void main(String[] args) {//普通煎饼Pancakes pancakes = new Pancakes();System.out.println(pancakes.getMsg()+",总价:"+pancakes.getPrice());//加了一个鸡蛋的煎饼PancakesWithEgg pancakesWithEgg = new PancakesWithEgg();System.out.println(pancakesWithEgg.getMsg()+",总价:"+pancakesWithEgg.getPrice());//加了一个鸡蛋和一根香肠的煎饼PancakesWithEggAndSausage pancakesWithEggAndSausage = new PancakesWithEggAndSausage();System.out.println(pancakesWithEggAndSausage.getMsg()+",总价:"+pancakesWithEggAndSausage.getPrice());}}

结果如下:

普通煎饼,总价:5
普通煎饼+1个鸡蛋,总价:6
普通煎饼+1个鸡蛋+1根香肠,总价:8

看起来没毛病,价格啥算的也都对,but,如果我下次还想再膨胀一下,再加点生菜或者加两个鸡蛋怎么办?如果按照这种方式,我还得再建一个加鸡蛋加香肠加生菜的煎饼对象,或者再建一个只加两个鸡蛋的煎饼对象,这样会导致我们的场景越来越复杂,这显然不是一个正常的写代码的方式。如何解决这个问题呢?重点来了,就是本次要介绍的装饰器模式。

先介绍下装饰器模式的概念:不改变原有对象的基础上,将功能附加到对象上,提供了比继承更有弹性的替代方案。嗯,还是有点抽象,继续举例说明,看看用装饰器模式如何解决我们的煎饼果子需求多的问题。

首先我们得定义一个抽象的煎饼组件,只用来描述煎饼的属性:

package com.rq.pattern.decorator.v2;/*** Title: Pancakes* Description: 煎饼抽象化组件,用来定义煎饼对象* @author RQ * @date 2020年4月12日*/
public abstract class Pancakes {public abstract String getMsg();public abstract int getPrice();}

接下来,我们定义基础版的煎饼,即不做任何升级的煎饼:

package com.rq.pattern.decorator.v2;/*** Title: BasePancake* Description: 基础版本的煎饼* @author RQ * @date 2020年4月12日*/
public class BasePancakes extends Pancakes{@Overridepublic String getMsg() {return "煎饼";}@Overridepublic int getPrice() {return 5;}}

再定义一个煎饼的装饰器:

package com.rq.pattern.decorator.v2;/*** Title: BasePancake* Description: 煎饼的装饰器,继承煎饼这个抽象组件* @author RQ * @date 2020年4月12日*/
public class PancakeDecorator extends Pancakes{private Pancakes pancakes;//定义带参数的构造方法,将抽象组件Pancakes传进来,要求下面所有的子类必须实现带参数的构造方法,参数就是抽象组件public PancakeDecorator(Pancakes pancakes) {this.pancakes = pancakes;}//这里的方法不做任何实现,直接调用传入对象的方法@Overridepublic String getMsg() {return this.pancakes.getMsg();}@Overridepublic int getPrice() {return this.pancakes.getPrice();}}

接下来就是根据各种需求,来定义不同的装饰器, 比如鸡蛋装饰器、香肠装饰器、生菜装饰器等等,在定义装饰器的时候,不管是什么,都要求必须继承最初的煎饼装饰器,我们就以鸡蛋装饰器和香肠装饰器来举例说明:

package com.rq.pattern.decorator.v2;/*** Title: BasePancake* Description: 加鸡蛋装饰器,继承煎饼的装饰器* @author RQ * @date 2020年4月12日*/
public class EggDecorator extends PancakeDecorator{public EggDecorator(Pancakes pancakes) {super(pancakes);}public String getMsg() {return super.getMsg()+"加1个鸡蛋";}public int getPrice() {return super.getPrice()+1;}}

 

package com.rq.pattern.decorator.v2;/*** Title: BasePancake* Description: 加香肠的装饰器,继承煎饼的装饰器* @author RQ * @date 2020年4月12日*/
public class SausageDecorator extends PancakeDecorator{public SausageDecorator(Pancakes pancakes) {super(pancakes);}public String getMsg() {return super.getMsg()+"加1根香肠";}public int getPrice() {return super.getPrice()+2;}}

装饰器建好后,看看如何使用装饰器来组装各种配置的煎饼:

package com.rq.pattern.decorator;import com.rq.pattern.decorator.v2.BasePancakes;
import com.rq.pattern.decorator.v2.EggDecorator;
import com.rq.pattern.decorator.v2.Pancakes;
import com.rq.pattern.decorator.v2.SausageDecorator;public class TestV2 {public static void main(String[] args) {//基础版煎饼Pancakes pancakes;pancakes = new BasePancakes();System.out.println(pancakes.getMsg()+",总价:"+pancakes.getPrice());//加一个鸡蛋的煎饼pancakes = new EggDecorator(pancakes);System.out.println(pancakes.getMsg()+",总价:"+pancakes.getPrice());//加一个鸡蛋和香肠的煎饼pancakes = new SausageDecorator(pancakes);System.out.println(pancakes.getMsg()+",总价:"+pancakes.getPrice());//只加两个鸡蛋的煎饼Pancakes pancakes2 = new BasePancakes();pancakes2 = new EggDecorator(pancakes2);pancakes2 = new EggDecorator(pancakes2);System.out.println(pancakes2.getMsg()+",总价:"+pancakes2.getPrice());}
}

运行结果:

煎饼,总价:5
煎饼加1个鸡蛋,总价:6
煎饼加1个鸡蛋加1根香肠,总价:8
煎饼加1个鸡蛋加1个鸡蛋,总价:7

对比两种方式,我们就能很清楚的了解了装饰器模式的概念以及使用场景了,以及装饰器模式能帮我们解决的问题。

更多推荐

Java设计模式学习笔记:装饰器模式

本文发布于:2024-02-06 04:10:43,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1746374.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模式   学习笔记   Java

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!