博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之装饰器模式
阅读量:3914 次
发布时间:2019-05-23

本文共 12195 字,大约阅读时间需要 40 分钟。

定义:装饰器模式(Decorator Pattern)也叫包装模式(Wrapper Pattern),是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能)

属于结构型模式

适用场景

1.用于扩展一个类的功能或给一个类添加附加职责
2.动态的给一个对象添加功能,这些功能可以再动态的撤销

优点

1.装饰器是继承的有力补充,比继承灵活,不改变原有对象的情况下动态地给一个对象扩展功能,即插即用
2.通过使用不同装饰类以及这些装饰类的排列组合,可实现不同效果
3.装饰器完全遵守开闭原则

装饰器模式和代理模式对比

1.装饰器模式就是一种特殊的代理模式
2.装饰器模式强调自身的功能扩展,透明的扩展,可动态定制的扩展
3.代理模式强调代理过程的控制

缺点

1.会出现更多的代码,更多的类,增加程序的复杂性
2.动态装饰时,多层装饰时会更复杂

例子

无装饰器模式
public class BatterCake {
protected String getMsg(){
return "煎饼";} protected int getPrice(){
return 5;}}
public class BatterCakeWithEgg extends BatterCake{
protected String getMsg(){
return super.getMsg() + " + 1 个鸡蛋";}; public int getPrice(){
return super.getPrice() + 2;}}
public class BatterCakeWithEggAndSauage extends BatterCakeWithEgg {
protected String getMsg(){
return super.getMsg() + " + 1 个香肠";}; public int getPrice(){
return super.getPrice() + 2;}}
public class Test {
public static void main(String[] args) {
BatterCake batterCake = new BatterCake(); System.out.println(batterCake.getMsg()+ ",总价: " + batterCake.getPrice()); BatterCakeWithEgg battercakeWithEgg = new BatterCakeWithEgg(); System.out.println(battercakeWithEgg.getMsg() + ",总价: " + battercakeWithEgg.getPrice()); BatterCakeWithEggAndSauage battercakeWithEggAndSauage = new BatterCakeWithEggAndSauage(); System.out.println(battercakeWithEggAndSauage.getMsg() + ",总价: " + battercakeWithEggAndSauage.getPrice()); }}
用装饰器模式之后(装饰器核心思想,继承或实现接口,然后添加接口为属性,并在构造方法中赋值,重写的方法内部是用接口调用相应的方法)
public abstract class BatterCake {
protected abstract String getMsg(); protected abstract int getPrice();}
public class BatterCakeDecorator extends BatterCake{
private BatterCake batterCake; public BatterCakeDecorator(BatterCake batterCake){
this.batterCake = batterCake; } @Override protected String getMsg() {
return this.batterCake.getMsg(); } @Override protected int getPrice() {
return this.batterCake.getPrice(); }}
public class BaseBatterCake extends BatterCake{
@Override protected String getMsg() {
return "煎饼"; } @Override protected int getPrice() {
return 5; }}
public class EggDecorator extends BatterCakeDecorator{
public EggDecorator(BatterCake batterCake){
super(batterCake); } @Override protected String getMsg() {
return super.getMsg() + " + 1 个鸡蛋"; } @Override protected int getPrice() {
return super.getPrice() + 2; }}
public class SauageDecorator extends BatterCakeDecorator{
public SauageDecorator(BatterCake batterCake){
super(batterCake); } @Override protected String getMsg() {
return super.getMsg() + " + 1 个香肠"; } @Override protected int getPrice() {
return super.getPrice() + 2; }}
public class PotatoDecorator extends BatterCakeDecorator{
public PotatoDecorator(BatterCake batterCake) {
super(batterCake); } protected String getMsg(){
return super.getMsg() + " + 土豆丝";} protected int getPrice(){
return super.getPrice() + 1;};}
public class Test {
public static void main(String[] args) {
BatterCake batterCake; batterCake = new BaseBatterCake(); batterCake = new EggDecorator(batterCake); batterCake = new EggDecorator(batterCake); batterCake = new SauageDecorator(batterCake); batterCake = new SauageDecorator(batterCake); batterCake = new PotatoDecorator(batterCake); batterCake = new PotatoDecorator(batterCake); batterCake = new PotatoDecorator(batterCake); System.out.println(batterCake.getMsg() + ",总价: " + batterCake.getPrice()); }}
使用装饰器模式将日志打印格式转成json格式
public class LoggerDecorator implements Logger {
protected Logger logger; public LoggerDecorator(Logger logger){
this.logger = logger; } @Override public String getName() {
return null; } @Override public boolean isTraceEnabled() {
return false; } @Override public void trace(String s) {
} @Override public void trace(String s, Object o) {
} @Override public void trace(String s, Object o, Object o1) {
} @Override public void trace(String s, Object... objects) {
} @Override public void trace(String s, Throwable throwable) {
} @Override public boolean isTraceEnabled(Marker marker) {
return false; } @Override public void trace(Marker marker, String s) {
} @Override public void trace(Marker marker, String s, Object o) {
} @Override public void trace(Marker marker, String s, Object o, Object o1) {
} @Override public void trace(Marker marker, String s, Object... objects) {
} @Override public void trace(Marker marker, String s, Throwable throwable) {
} @Override public boolean isDebugEnabled() {
return false; } @Override public void debug(String s) {
} @Override public void debug(String s, Object o) {
} @Override public void debug(String s, Object o, Object o1) {
} @Override public void debug(String s, Object... objects) {
} @Override public void debug(String s, Throwable throwable) {
} @Override public boolean isDebugEnabled(Marker marker) {
return false; } @Override public void debug(Marker marker, String s) {
} @Override public void debug(Marker marker, String s, Object o) {
} @Override public void debug(Marker marker, String s, Object o, Object o1) {
} @Override public void debug(Marker marker, String s, Object... objects) {
} @Override public void debug(Marker marker, String s, Throwable throwable) {
} @Override public boolean isInfoEnabled() {
return false; } @Override public void info(String s) {
} @Override public void info(String s, Object o) {
} @Override public void info(String s, Object o, Object o1) {
} @Override public void info(String s, Object... objects) {
} @Override public void info(String s, Throwable throwable) {
} @Override public boolean isInfoEnabled(Marker marker) {
return false; } @Override public void info(Marker marker, String s) {
} @Override public void info(Marker marker, String s, Object o) {
} @Override public void info(Marker marker, String s, Object o, Object o1) {
} @Override public void info(Marker marker, String s, Object... objects) {
} @Override public void info(Marker marker, String s, Throwable throwable) {
} @Override public boolean isWarnEnabled() {
return false; } @Override public void warn(String s) {
} @Override public void warn(String s, Object o) {
} @Override public void warn(String s, Object... objects) {
} @Override public void warn(String s, Object o, Object o1) {
} @Override public void warn(String s, Throwable throwable) {
} @Override public boolean isWarnEnabled(Marker marker) {
return false; } @Override public void warn(Marker marker, String s) {
} @Override public void warn(Marker marker, String s, Object o) {
} @Override public void warn(Marker marker, String s, Object o, Object o1) {
} @Override public void warn(Marker marker, String s, Object... objects) {
} @Override public void warn(Marker marker, String s, Throwable throwable) {
} @Override public boolean isErrorEnabled() {
return false; } @Override public void error(String s) {
} @Override public void error(String s, Object o) {
} @Override public void error(String s, Object o, Object o1) {
} @Override public void error(String s, Object... objects) {
} @Override public void error(String s, Throwable throwable) {
} @Override public boolean isErrorEnabled(Marker marker) {
return false; } @Override public void error(Marker marker, String s) {
} @Override public void error(Marker marker, String s, Object o) {
} @Override public void error(Marker marker, String s, Object o, Object o1) {
} @Override public void error(Marker marker, String s, Object... objects) {
} @Override public void error(Marker marker, String s, Throwable throwable) {
}}
public class JsonLogger extends LoggerDecorator{
public JsonLogger(Logger logger) {
super(logger); } @Override public void info(String s) {
JSONObject result = newJsonObject(); result.put("message: ",s); logger.info(result.toString()); } @Override public void error(String s) {
JSONObject result = newJsonObject(); result.put("error: ",s); logger.info(result.toString()); } public void error(Exception e){
JSONObject result = newJsonObject(); result.put("exception: ",e); String trace = Arrays.toString(e.getStackTrace()); result.put("starckTrace: ",trace); logger.info(result.toString()); } private JSONObject newJsonObject(){
return new JSONObject(); }}
public class JsonLoggerFactory {
public static JsonLogger getLogger(Class clazz){
Logger logger = LoggerFactory.getLogger(clazz); return new JsonLogger(logger); }}
public class Test {
//private static final Logger logger = LoggerFactory.getLogger(Test.class); private static final Logger logger = JsonLoggerFactory.getLogger(Test.class); public static void main(String[] args) {
logger.error("系统错误"); }}
装饰器模式经典结构
public abstract class Component {
abstract void operation();}
public abstract class Decorator extends Component {
//持有组件对象 protected Component component; /** * 构造方法,传入组件对象 * @param component */ public Decorator(Component component){
this.component = component; }; public void operation(){
//转发请求给组件对象,可以在转发前后执行一些附加动作 component.operation(); }}
public class ConcreteComponent extends Component{
@Override void operation() {
System.out.println("我是第二级"); }}
public class ConcreteDecoratorA extends Decorator {
/** * 构造方法,传入组件对象 * * @param component */ public ConcreteDecoratorA(Component component) {
super(component); } private void operationFirst(){
System.out.println("执行前操作A"); };//在调用父类的operation方法之前需要执行的操作 private void operationLast(){
System.out.println("执行后操作A"); };//在调用父类的operation方法之后需要执行的操作 public void operation(){
//调用父类的方法,可以在调用前后执行一些附加动作 operationFirst();//添加的功能 super.operation();//这里可以选择性的调用父类的方法,如果不调用则相当于完全改写了方法, operationLast();//添加的功能 }}
public class ConcreteDecoratorB extends Decorator{
/** * 构造方法,传入组件对象 * * @param component */ public ConcreteDecoratorB(Component component) {
super(component); } private void operationFirst(){
System.out.println("执行前操作B"); };//在调用父类的operation方法之前需要执行的操作 private void operationLast(){
System.out.println("执行后操作B"); };//在调用父类的operation方法之后需要执行的操作 public void operation(){
//调用父类的方法,可以在调用前后执行一些附加动作 operationFirst();//添加的功能 super.operation();//这里可以选择性的调用父类的方法,如果不调用则相当于完全改写了方法, operationLast();//添加的功能 }}
public class Client {
public static void main(String[] args) {
Component component = new ConcreteComponent(); Decorator decoratorA = new ConcreteDecoratorA(component); decoratorA.operation(); Decorator decoratorB = new ConcreteDecoratorB(component); decoratorB.operation(); Decorator decoratorBandA = new ConcreteDecoratorB(decoratorA); decoratorBandA.operation(); }}

转载地址:http://nkjrn.baihongyu.com/

你可能感兴趣的文章
数据库单表千万行 LIKE 搜索优化手记
查看>>
在香蕉派的树莓派系统上配置 Syncthing 自启动(暨 Linux 软件自启服务配置)
查看>>
活久见!月薪30k的小程序全栈开发到底有多难?
查看>>
C# 枚举转列表
查看>>
动态 Restful API 生成
查看>>
终于弄明白了 Singleton,Transient,Scoped 的作用域是如何实现的
查看>>
我们真的需要JWT吗?
查看>>
CLR的简单理解
查看>>
把Autofac玩的和java Spring一样6
查看>>
关于技术规划的想法
查看>>
使用BeetleX在Linux下部署.NET多站点服务
查看>>
[C#.NET 拾遗补漏]08:强大的LINQ
查看>>
排坑 | Exceptionless 5.x 无法正常发送邮件
查看>>
一名“企业定制化人才”的自诉:“我不愿意,但却无可奈何”
查看>>
高效掌握新技能的「树型思维」
查看>>
ABP VNext实践之搭建可用于生产的IdentityServer4
查看>>
.NET Core 中生成验证码
查看>>
.NET Core 中导入导出Excel
查看>>
初识ABP vNext(8):ABP特征管理
查看>>
WPF 消息框 TextBox 绑定新数据时让光标和滚动条跳到最下面
查看>>