设计模式-装饰者模式(Decorator Pattern)

1.装饰者模式

1.1装饰者模式介绍

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

装饰者设计模式

如图看上去有点像套娃,而装饰器的核心是再不改变原有类的基础上添加功能,有的同学就想到用继承、AOP切面,当然都可以实现,单单继承实现是有局限性的,且会造成子类过多,AOP实现较为复杂。装饰者模式会是一种更加灵活的思路,都避免了以上问题。

主要解决: 一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

优点: 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点: 多层装饰比较复杂。

用例场景: 1、毛坯房装修的豪华靓丽,本质还是钢筋水泥。2、孙悟空拥有72变,当变成其他动物的时候,本质还是猴子。

1.2案例场景

描述: 猪(Pig)和鸭(Duck)都属于动物(Animal),他们都会吃饭(eat)。在不改变他们本质的情况下,给这些动物增加跑(run)和飞(fly)的功能。

实现:

  • 创建Animal接口和实现类Pig和Duck。
  • 然后创建一个实现了Animal接口的抽象类AnimalDecorator,并把Animal作为成员变量。
  • OtherAnimalDecorator类继承AnimalDecorator实现对应的方法。

场景代码实现:

1)创建基础接口和类:Animal接口、Pig类、Duck类

/**
 * 动物接口
 */
public interface Animal {
	void eat();
}

/**
 * 猪类
 */
public class Pig implements Animal {
	@Override
	public void eat() {
		System.out.println("Pig: eat");
	}
}

/**
 * 鸭类
 */
public class Duck implements Animal {
	@Override
	public void eat() {
		System.out.println("Duck: eat");
	}
}

2)创建AnimalDecorator抽象装饰器类和OtherAnimalDecorator装饰器类,用于扩展fly和run的功能。

/**
 * 动物装饰器类实现动物接口
 */
static abstract class AnimalDecorator implements Animal {
	// 动物实现接口
	protected Animal animal;
	// 用于实例化,触发实现该接口的类
	public AnimalDecorator(Animal animal) {
		this.animal = animal;
	}
}

/**
 * 继承装饰器类,用于扩展功能
 */
public class OtherAnimalDecorator extends AnimalDecorator {
	// 实例化的时候传入对应的动物,用于调用对应的方法
	public OtherAnimalDecorator(Animal animal) {
		super(animal);
	}
	// 给传入的动物赋予其他功能
	@Override
	public void eat() {
		animal.eat();
		fly();
		run();
	}
	public void fly() {
		System.out.println("Animal: fly");
	}
	public void run() {
		System.out.println("Animal: run");
	}
}

/**
 * 使用OtherAnimalDecorator装饰AnimalDecorator类
 */
public class DecoratorTest {
	public static void main(String[] args) {
		Animal pig = new Pig();
		Animal duck = new Duck();
        
		AnimalDecorator otherPig = new OtherAnimalDecorator(pig);
		AnimalDecorator otherDuck = new OtherAnimalDecorator(duck);
        
		System.out.println("===========pig==========");
		pig.eat();
		System.out.println("===========duck==========");
		duck.eat();
		System.out.println("===========otherPig==========");
		otherPig.eat();
		System.out.println("===========otherDuck==========");
		otherDuck.eat();
	}
}

3)输出如下:

===========pig==========
Pig: eat
===========duck==========
Duck: eat
===========otherPig==========
Pig: eat
Animal: fly
Animal: run
===========otherDuck==========
Duck: eat
Animal: fly
Animal: run

1.3总结

  • 可以看到每一类动物除了eat之外,还会有fly和run的功能。
  • 如果不使用装饰者模式来实现,单单用继承来实现会用到多次继承,要是用ifelse,那后续的扩展变得更加复杂。
  • 使用装饰器模式满足单一职责原则,你可以在自己的装饰类中完成功能逻辑的扩展,而不影响主类,同时可以按需在运行时添加和删除这部分逻辑。

参考:《重学Java设计模式》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值