ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

设计模式-装饰者模式

2022-04-20 23:32:02  阅读:160  来源: 互联网

标签:Pig eat AnimalDecorator 模式 装饰 Animal 设计模式 public


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设计模式》

标签:Pig,eat,AnimalDecorator,模式,装饰,Animal,设计模式,public
来源: https://www.cnblogs.com/cnwanj/p/16172324.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有