什么是装饰模式?
动态地给一个对象添加一些额外的职责。
装饰模式也称为包装模式,本着对客户端透明的方式来动态扩展对象的功能。相比增加功能来说他比继承生成子类更加灵活,使用更加简便。
装饰模式适用场景
需要透明地动态扩展类的功能(比如奶油蛋糕本体是奶油蛋糕,扩展需要加水果或者花朵装饰物,而装饰物的品类是动态添加种类也不固定的)
装饰模式用例
人是被装饰的本体,性别分为男女等。装饰类有上衣、裤子、裙子等。
UML类图:
Person类:
public abstract class Person {
abstract void dressed();
}
Boy类:
public class Boy extends Person {
@Override
void dressed() {
System.out.println("I am a boy");
}
}
Girl类:
public class Girl extends Person {
@Override
void dressed() {
System.out.println("I am a girl");
}
}
DecoratorCloth类:
public abstract class DecoratorCloth extends Person {
protected Person person;
public DecoratorCloth(Person person){
this.person = person;
}
@Override
void dressed() {
person.dressed();
}
}
Pants类:
public class Pants extends DecoratorCloth {
public Pants(Person person) {
super(person);
}
private void dressedPants(){
System.out.println("穿上了牛仔裤");
}
public void dressed(){
super.dressed();
dressedPants();
}
}
Skirt类:
public class Skirt extends DecoratorCloth {
public Skirt(Person person) {
super(person);
}
private void dressedSkirt(){
System.out.println("穿上了裙子");
}
public void dressed(){
super.dressed();
dressedSkirt();
}
}
Coat类:
public class Coat extends DecoratorCloth {
public Coat(Person person) {
super(person);
}
private void dressedCoat(){
System.out.println("穿上了外套");
}
public void dressed(){
super.dressed();
dressedCoat();
}
}
主类调用:
public class Test {
public static void main(String[] args) {
//new个男孩子
Person boy = new Boy();
//穿牛仔裤
DecoratorCloth dc = new Pants(boy);
dc.dressed();
//穿上衣
DecoratorCloth dc2 = new Coat(boy);
dc2.dressed();
}
}
运行结果:
I am a boy
穿上了牛仔裤
I am a boy
穿上了外套
总结:整个系统结构很清晰,动态的意思就是你想换衣服就可以随便换,新加类也很方便,比如你买了新的鞋子,只需要扩展DecoratorCloth为 Shoes即可。整个系统是类之间的封装。
优点:是继承关系的以个代替方案,动态增加对象功能,实现简介方便。把核心职责和装饰功能分离开来。降低耦合度。
缺点:多层装饰实现起来就比较棘手,易出错。