装饰者设计模式的简单了解

本篇供个人学习使用,有问题欢迎讨论

装饰者设计模式

一、什么是装饰者设计模式

​ Decorator Pattern,能够在不修改目标类也不使用继承的情况下,动态地扩展一个类的功能。它是通过创建一个包装对象,也就是装饰者来达到增强目标类的目的的。

​ 装饰者设计模式的实现有两个要求:

  • 装饰者类与目标类要实现相同的接口,或继承自相同的抽象类

  • 装饰者类中要有目标类的引用作为成员变量,而具体的赋值一般通过带参构造器完成

​ 这两个要求的目的是,在装饰者类中的方法可以调用目标类的方法,以增强这个方法。而增强的这个方法是通过重写的方式进行的增强,所以要求实现相同的接口或继承相同的抽象类。

​ 在装饰者设计模式中,装饰者类一般是不对目标类进行增强的。装饰者类作为一个基类,具体的装饰者继承自这个基类,对目标类进行具体的、单功能的增强。这样做的好处是,在很方便的情况下可以实现多重地、组合式地增强。

二、装饰者设计模式的用法

1、基本用法

如实现对一个字符串的大写功能:

ISomeService(接口):

public interface ISomeService {
    String doSome();
}

SomeServiceImpl(目标类):

public class SomeServiceImpl implements ISomeService {
    public String doSome() {
        return "abc";
    }
}

SomeServiceDecorator(装饰者):

public class SomeServiceDecorator implements ISomeService {
    private ISomeService target; //目标对象

    //通过带参构造器传入目标对象
    public SomeServiceDecorator(ISomeService target) {
        this.target = target;
    }

    public String doSome() {
        return target.doSome().toUpperCase();
    }
}

测试:

public class Test02 {
    public static void main(String[] args) {
        //创建目标对象
        ISomeService target = new SomeServiceImpl();
        //使用目标对象作为参数,创建装饰者
        ISomeService service = new SomeServiceDecorator(target);
        //使用装饰者的业务方法
        String result = service.doSome();
        System.out.println("result = " + result);
    }
}

输出结果:
在这里插入图片描述

2、高级用法

如实现对一个字符串的大写和忽略前后空白的功能:

ISomeService(接口):

public interface ISomeService {
    String doSome();
}

SomeServiceImpl(目标类):

public class SomeServiceImpl implements ISomeService {
    public String doSome() {
        return "  abc  ";
    }
}

SomeServiceWrapper(基类):

  • 要有无参构造器
  • 不对目标类的目标方法进行任何增强
public class SomeServiceWrapper implements ISomeService {
    private ISomeService target; //目标对象
    //无参构造
    public SomeServiceWrapper() {
    }
    //通过带参构造器传入目标对象
    public SomeServiceWrapper(ISomeService target) {
        this.target = target;
    }
    //调用目标类的目标方法,但不对其进行任何的增强
    public String doSome() {
        return target.doSome();
    }
}

TrimDecorator(具体装饰者):

  1. 要继承自装饰者基类
  2. 要有带参构造器
  3. 具体装饰者只对装饰者基类业务方法进行某一种单一的增强
public class TrimDecorator extends SomeServiceWrapper {
    public TrimDecorator() {
    }

    public TrimDecorator(ISomeService target) {
        super(target);
    }

    //重写基类的业务方法
    public String doSome() {
        //调用基类的业务方法,并对其进行增强
        return super.doSome().trim();
    }
}

ToUpperCaseDecorator(具体装饰者):

public class ToUpperCaseDecorator extends SomeServiceWrapper {
    public ToUpperCaseDecorator() {
    }

    public ToUpperCaseDecorator(ISomeService target) {
        super(target);
    }

    public String doSome() {
        return super.doSome().toUpperCase();
    }
}

测试:

public class Test02 {
    public static void main(String[] args) {
        //创建目标对象
        ISomeService target = new SomeServiceImpl();
        //使用目标对象作为参数,创建装饰者
        ISomeService service = new TrimDecorator(target);
        //将第一次增强过的结果作为第二次增强的参数出现,形成“装饰者链”
        ISomeService service2 = new ToUpperCaseDecorator(service);
        //使用装饰者的业务方法
        String result = service2.doSome();
        System.out.println("result = " + result);
    }
}

输出结果(使用“装饰者”之前):
在这里插入图片描述
使用“装饰者”之后:
在这里插入图片描述

三、静态代理设计模式

ISomeService(接口):

public interface ISomeService {
    String doSome();
}

SomeServiceImpl(目标类):

public class SomeServiceImpl implements ISomeService {
    public String doSome() {
        return "  abc  ";
    }
}

OtherServiceProxy(静态代理类):

public class OtherServiceProxy implements ISomeService {
    private ISomeService target;
    //在无参构造器中创建目标对象
    public OtherServiceProxy() {
        target = new SomeServiceImpl();
    }

    public String doSome() {
        return target.doSome().toUpperCase();
    }
}

测试:

public class Test03 {
    public static void main(String[] args) {
        ISomeService service = new OtherServiceProxy();
        String result = service.doSome();
        System.out.println("result = " + result);

    }
}

输出结果:
在这里插入图片描述

四、装饰者设计模式与静态代理设计模式的对比

静态代理类与装饰者间的共同点

  1. 都要实现与目标类相同的业务接口
  2. 这两个类中都要声明目标对象
  3. 都可以在不修改目标类的前提下增强目标方法

静态代理类与装饰者间的区别

  1. 使用目的不同
    装饰者的使用目的是:就是增 强目标对象
    静态代理的使用目的是:是为保护和隐藏目标对象

  2. 对于目标对象的获取方式不同

    ​ 装饰者类中目标对象的获取:通过带参构造器传入
    ​ 静态代理中目标对象的获取:在无参构造器中直接创建

  3. 功能增强的实现者不同

    ​ 装饰者设计模式中存在装饰者基类,其并不真正实现增强,而是=由具体的装饰者进行功能增强的,所以存在一个 “ 装饰者链 “ 的概念
    ​ 静态代理设计模式中一般不存在父子类的关系,具体的增强,就是由代理类完成,无需其子类完成,所以不存在 “ 链 ” 的概念

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值