提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、问题描述
变形金刚在变形之前是一辆汽车,它可以在陆地上移动。当它变成机器人之后除了能够在陆地上移动之外,还可以说话;如果需要,它还可以变成飞机,除了在陆地上移动还可以在天空中飞翔。使用装饰模式设计类图并编程实现。
二、问题分析
1.类图
三、装饰模式简介
装饰模式(Decorator Pattern):动态地给一个对象增加一个额外的职责,就增加对象功能来说,装配模式比生成子类实现更为灵活。
1.装饰模式的优点
(1)对于扩展一个对象的功能,装修模式比集成模式更加灵活,不会导致类的个数急剧增加。
(2)可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的具体装饰类,从而实现不同的行动。
(3)可以对一个对象进行多次装饰,通过使用不同的具体装饰类,以及这些装饰类的排列组合,可以创造出很多不同行为的组合,得到功能更强大的对象。
(4)具体构建类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构建类和具体装饰类,原来类库代码无须改变,符合开闭原则。
2.装饰模式的缺点
(1)使用装饰模式进行系统设计时将产生很多小对象,这些对象的区分在与他们之间相互连接的方式有所不同,而不是他们的类或者属性有所不同,大量小对象的产生势必会占用更多的系统资源,在一定程度上印象程序的性能。
(2)装饰模式的提供了一种比继承更加灵活机动的解决方案,但是同时也意味着比继承更加易于出错,排除也很困难,对于多次装饰的对象,调试时群钊错误可能需要逐级排查,比较繁琐。
3.应用场景
装饰模式通常适用于以下场景:
(1)在不影响其他对象的情况下,以动态、透明的方式给单个对象增加职责。
(2)当不能采用集成的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式:系统存在独立的大量类。已经被定义不能继承。
4.透明装饰模式与半透明模式
透明模式:透明性要求客户端程序不应该将对象生命为具体构建类型或具体装饰类型,而应该全部声明称抽象构建类型。
半透明模式:设计难度大,用户需要单独调用新增业务方法,为了能够调用到新增方法,不得不利用具体装修类型来定义装饰模式之后对象,而是具体构建类型还是可以使用抽象构建类型定义。
四、代码及结果
Transformers抽象类:
public abstract class Transformers {
public abstract void move();
}
具体构件类——Car:
public class Car extends Transformers{
public Car()
{
System.out.println("变形金刚是一辆车");
}
@Override
public void move() {
System.out.println("在陆地上移动");
}
}
具体构件类——SuperCar:
public class SuperCar extends Transformers{
@Override
public void move() {
System.out.println("超级汽车人移动");
}
}
抽象装饰类——ComponentDecorator:
public class ComponentDecorator extends Transformers{
private Transformers transformers;
public ComponentDecorator(Transformers transformers)
{
this.transformers=transformers;
System.out.println("汽车人变形!");
}
public void move(){
transformers.move();
};
}
具体装饰类——Robot(另一个具体装饰类类似):
public class Robot extends ComponentDecorator{
public Robot(Transformers transformers) {
super(transformers);
System.out.println("变成机器人");
}
public void say()
{
System.out.println("可以说话");
}
@Override
public void move() {
super.move();
say();
}
}
Client类:
public class Client {
public static void main(String args[])
{
Transformers transformers0,transformers1 ,transformers2,transformers3;
transformers1 = new Car();
transformers0 = new SuperCar();
System.out.println("----------------------");
transformers2 = new Robot(transformers1);
transformers2.move();
System.out.println("----------------------");
transformers2 = new Robot(transformers0);
transformers2.move();
System.out.println("----------------------");
transformers3 = new AirPlane(transformers2);
transformers3.move();
}
}
运行结果为:此处第三次进行了二重装饰。