结构模式之装饰模式

编程

1 概述

装饰模式(Decorator Pattern),意在不改变原有对象的情况下,改变/增强它的方法。

2 装饰模式

在不违反开闭原则的前提下,要改变某个对象的行为,可以使用继承。然而继承不适用于类/方法被final修饰的情况,而且一般需要了解类内部的情况,违反了迪米特法则。

装饰模式体现了组合优先于继承的思想,通过组合的方式,“装饰”对象的功能,也能达到改变对象行为的目的。装饰模式的实现模式和代理模式很相似,都是实现目标对象的接口,然后持有目标类,调用目标类的方法。代理模式更偏向于对对象的控制,给对象添加与其无关的功能(打日志,权限校验等);而装饰模式更偏向于对对象的增强,即增强对象原有的方法,装饰后的对象还是原来的对象。

3 案例

举个例子。定义一个Car接口,看如何用装饰模式在不修改原有对象的基础上,对其方法进行增强:

public class Test {

public static void main(String[] args) {

Car basicCar = new BasicCar();

// 装饰类

Car sportsCar = new SportsCar(basicCar);

basicCar.drive();

System.out.println("top speed of basic car: " + basicCar.topSpeed());

System.out.println("=============");

sportsCar.drive();

System.out.println("top speed of sports car: " + sportsCar.topSpeed());

}

}

public interface Car {

void drive();

int topSpeed();

}

public class BasicCar implements Car {

[@Override](https://my.oschina.net/u/1162528)

public void drive() {

System.out.println("Car is driving...");

}

[@Override](https://my.oschina.net/u/1162528)

public int topSpeed() {

return 120;

}

}

// 装饰类

public class SportsCar implements Car {

// 被装饰对象

Car car;

SportsCar(Car car) {

this.car = car;

}

// 对drive()方法进行增强

[@Override](https://my.oschina.net/u/1162528)

public void drive() {

System.out.println("Sports Car is build with high performance engine...");

car.drive();

}

// 对topSpeed()方法进行增强

[@Override](https://my.oschina.net/u/1162528)

public int topSpeed() {

return car.topSpeed() + 60;

}

}

输出:

Car is driving...

top speed of basic car: 120

=============

Sports Car is build with high performance engine...

Car is driving...

top speed of sports car: 180

装饰类SportsCar实现了被装饰对象的接口,同时持有被装饰对象的实例,在调用被装饰对象的方法前后进行“装饰”。不影响原有类BasicCar的逻辑,符合开闭原则。

JavaCollections工具类就使用了装饰模式,synchronizedCollection(Collection<T> c)方法返回了一个装饰对象,对集合添加了同步处理,unmodifiableCollection(Collection<? extends T> c)方法返回了一个装饰对象,使得集合不能被修改。

4 总结

使用装饰模式可以在不改变原对象逻辑的情况下,实现对象方法的增强。

文中例子的github地址

以上是 结构模式之装饰模式 的全部内容, 来源链接: utcz.com/z/515631.html

回到顶部