(9)装饰者模式

一、问题:怎样对一个类的方法进行增强?

  • 基于继承:基于继承的增强,必须是可以自己手动创建子类对象
  • 基于装饰者模式(包装类) 
  • 基于动态代理

二、装饰者模式

        装饰者模式是在已有功能的基础之上,动态地添加更多功能的一种方式,这些新加的代码装饰了原有类的核心职责或主要行为。是继承的替代方案。

优点:使用装饰模式,可以提供比继承更灵活的扩展对象的功能,它可以动态的添加对象的功能,并且可以随意的组合这些功能

缺点:正因为可以随意组合,所以就可能出现一些不合理的逻辑

三、装饰者模式和继承的区别

继承实现的增强类:

  优点:代码结构清晰,而且实现简单

  缺点:对于每一个的需要增强的类都要创建具体的子类来帮助其增强,这样会导致继承体系过于庞大

装饰者模式实现的增强类:

  优点:内部可以通过多态技术对多个需要增强的类进行增强

  缺点:需要内部通过多态技术维护需要增强的类的实例。进而使得代码稍微复杂如果需要实现的接口方法特别多,接口的方法,其他方法也需要一一实现.

常用的装饰着模式的地方:IO流

四、装饰者模式实现的步骤

  1. 创建一个包装类,实现/继承与被包装类相同的接口/父类
  2. 在包装类中创建构造方法将被包装类传入进去
  3. 对要加强的方法进行逻辑重写,不需要加强的方法调用被包装类的方法

接口:Animal

/**
 * 动物接口类
 */
public interface Animal {
    /**
     * 吃的行为
     */
    void eat();

    /**
     * 移动的行为
     */
    void move();
}

实现类:Cat

/**
 * 被增强类(被包装类)-Cat类
 */
public class Cat implements Animal {

    @Override
    public void eat() {
        System.out.println("吃鱼");
    }

    @Override
    public void move() {
        System.out.println("小步走");
    }
}

装饰抽象类,需要实现Animal接口,传入被包装类,实现接口的方法调用被包装类的方法

/**
 * 装饰抽象类(包装抽象类)
 */
public abstract class AbstractDecorateAnimal implements Animal {

    /**
     * 传入被包装类,用于调用不需要增强的方法
     */
    protected Animal animal;

    public AbstractDecorateAnimal(Animal animal){
        this.animal = animal;
    }
    /**
     * 不增强的方法,调用被装饰的类的方法
     */
    @Override
    public void move() {
        animal.move();
    }

    @Override
    public void eat() {
        animal.eat();
    }
}

装饰类,需要继承装饰抽象类

/**
 * 装饰类(包装类),实际增强类
 */
public class DecorateCat extends AbstractDecorateAnimal {

    public DecorateCat(Animal animal) {
        super(animal);
    }

    /**
     * 加强吃的行为
     */
    @Override
    public void eat() {
        how();
        super.eat();
    }

    private void how(){
        System.out.print("坐凳子上");
    }
}

 5.demo

public class Test {
    public static void main(String[] args) {
        //创建需要增强的类
        Animal cat = new Cat();
        System.out.println("未增强eat:");
        cat.eat();
        cat.move();

        //Cat类进行抽象包装(增强)
        DecorateCat enhanceCat = new DecorateCat(cat);
        //加强后的eat
        System.out.println("增强enhanceCat:");
        enhanceCat.eat();
        enhanceCat.move();
    }
}

例子二

BufferedInputStream bi = new BufferedInputStream(new FileInputStream);
BufferedInputStream 就是InputStream一个包装类

我们可以通过装饰者模式(包装类)对Connection的close方法进行增强。
EnhanceConnection conn = new EnhanceConnection(conn);
//参数conn是通过原始的DriverManager获取的Connection对象
//EnhanceConnection 是conn的一个包装类,作用是对conn 的close方法进行增强的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值