Java SE装饰器设计模式
CAMELLIA!!! note 目录
装饰器设计模式
一、为何提出装饰器设计模式?
在我们完成业务之后可能要求添加新的行为,如果直接在类本身改的话不符合OCP原则。还有一种方式就是对我的类再实现子类,在子类中实现要添加的新功能,但是会引起类爆炸。
1 2 3 4
| package com.camellia.io.decorator.package01; public interface Flyable { void fly(); }
|
1 2 3 4 5 6 7
| package com.camellia.io.decorator.package01; public class Cat implements Flyable{ @Override public void fly() { System.out.println("Cat fly"); } }
|
1 2 3 4 5 6 7
| package com.camellia.io.decorator.package01; public class Bird implements Flyable{ @Override public void fly() { System.out.println("Bird fly!"); } }
|
1 2 3 4 5 6 7 8 9 10
| package com.camellia.io.decorator.package01;
public class CatSub extends Cat{ @Override public void fly() { super.fly(); System.out.println("Cat 新方法"); } }
|
1 2 3 4 5 6 7 8
| package com.camellia.io.decorator.package01; public class BirdSub extends Bird{ @Override public void fly() { super.fly(); System.out.println("Bird 新方法"); } }
|
耦合度高,且会发生类爆炸。
二、装饰器设计模式
2.1 主要目标
装饰器设计模式的主要目标是在不修改现有代码的情况下,动态地为对象添加新功能。这种方式可以保持代码的松耦合,同时提高系统的灵活性和可维护性。
2.1 重要角色
装饰者(Decorator):
被装饰者(Component):
- 被动态添加新功能的对象。
- 提供一个接口或抽象类,装饰者和被装饰者都实现或继承这个接口或抽象类。
2.3 装饰器模式要求
在装饰器设计模式中,装饰者和被装饰者必须实现相同的接口或继承相同的抽象类。这样做可以确保装饰者能够替代被装饰者,而客户端代码无需知道它们的区别。
2.4 为什么装饰者和被装饰者要实现同一个接口
当装饰者和被装饰者实现相同的接口时,客户端可以透明地使用装饰者,就像在使用被装饰者一样。这使得我们可以在不修改客户端代码的情况下,动态地为对象添加功能。
*2.5 装饰者包含被装饰者的引用
装饰者持有被装饰者的引用,这样可以在运行时动态地组合多个装饰者,为对象添加不同的功能。这种设计方式(”A has a B”)比继承(”is a”)更灵活,也降低了系统的耦合度。
三、示例代码(初步)
1 2 3 4 5
| package com.camellia.io.decorator.package02;
public interface Flyable { void fly(); }
|
1 2 3 4 5 6 7 8 9
| package com.camellia.io.decorator.package02;
public class Bird implements Flyable { @Override public void fly() { System.out.println("Bird fly!"); } }
|
1 2 3 4 5 6 7 8 9 10
| package com.camellia.io.decorator.package02;
public class Cat implements Flyable { @Override public void fly() { System.out.println("Cat fly!"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| package com.camellia.io.decorator.package02;
import java.text.SimpleDateFormat; import java.util.Date;
public class LogDecorator implements Flyable {
private Flyable flyable;
public LogDecorator(Flyable flyable) { this.flyable = flyable; }
@Override public void fly() { Date now = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); System.out.println(sdf.format(now) + ": 起飞前的准备");
flyable.fly();
now = new Date(); System.out.println(sdf.format(now) + ": 安全降落"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| package com.camellia.io.decorator.package02;
public class TimerDecorator implements Flyable {
private Flyable flyable;
public TimerDecorator(Flyable flyable) { this.flyable = flyable; }
@Override public void fly() { long begin = System.currentTimeMillis();
flyable.fly();
long end = System.currentTimeMillis();
System.out.println("耗时 " + (end - begin) + " 毫秒"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package com.camellia.io.decorator.package02;
public class ZMain { public static void main(String[] args) { Flyable flyable1 = new TimerDecorator(new Cat()); flyable1.fly();
Flyable flyable2 = new LogDecorator(new Bird()); flyable2.fly(); } }
|
这样虽然满足需求但是一旦装饰者多了不利于维护,我们可以提取公共的部分放到一个抽象父类中。
三、示例代码
1 2 3 4 5 6
| package com.camellia.io.decorator.package03;
public interface Flyable { void fly(); }
|
1 2 3 4 5 6 7 8 9 10
| package com.camellia.io.decorator.package03;
public class Bird implements Flyable{ @Override public void fly() { System.out.println("Bird fly!"); } }
|
1 2 3 4 5 6 7 8 9 10
| package com.camellia.io.decorator.package03;
public class Cat implements Flyable{ @Override public void fly() { System.out.println("Cat fly!"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package com.camellia.io.decorator.package03;
public abstract class FlyableDecorator implements Flyable { private Flyable flyable;
public FlyableDecorator(Flyable flyable) { this.flyable = flyable; }
@Override public void fly() { flyable.fly(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| package com.camellia.io.decorator.package03;
public class TimerDecorator extends FlyableDecorator {
public TimerDecorator(Flyable flyable) { super(flyable); }
@Override public void fly() { long begin = System.currentTimeMillis();
super.fly();
long end = System.currentTimeMillis();
System.out.println("耗时 " + (end - begin) + " 毫秒"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package com.camellia.io.decorator.package03;
public class ZMain { public static void main(String[] args) { Flyable flyable1 = new TimerDecorator(new Cat()); flyable1.fly();
Flyable flyable2 = new LogDecorator(new Bird()); flyable2.fly(); } }
|
五、类图