装饰者模式
个人感觉装饰者模式很像我们小的时候玩的变形金刚,最初变形金刚没有任何功能,就是纯粹的一个机器人(被装饰的对象),然后我们给变形金刚装上翅膀,它就会飞了,给它装上防水装甲,它就可以在水里游了。而这些所谓的翅膀、防水装甲就是我们今天要讲的装饰者。OK,下面我们以汽车的例子给大家介绍。
首先我们定义一辆汽车Car.java,这辆车既可以飞,又可以游,当然也可以跑~
package decorator01;
public class Car {
//跑
public void run(){
System.out.println("可以跑");
}
//飞
public void fly(){
System.out.println("可以飞");
}
//游
public void swim(){
System.out.println("可以游");
}
}
然后我们调用一下
package decorator01;
public class MainClass {
public static void main(String[] args) {
Car bus = new Car();
bus.run();
bus.fly();
bus.swim();
}
}
但是我们貌似发现了一个问题,我们在main函数里面只是想造一辆bus而已,bus需要会飞,需要会游吗?好吧,我们来改一改~我们把Car变成一个接口
package decorator03;
public interface Car {
public void show();
public void run();
}
然后我们根据具体的需求分别造出普通的车(RunCar.java),会飞的车(FlyCar.java),会游的车(SwimCar.java)
RunCar.java:
package decorator03;
public class RunCar implements Car {
@Override
public void show() {
this.run();
}
public void run(){
System.out.println("可以跑");
}
}
FlyCar.java:
package decorator03;
public class FlyCar implements Car {
@Override
public void show() {
this.run();
this.fly();
}
public void run(){
System.out.println("可以跑");
}
public void fly(){
System.out.println("可以飞");
}
}
SwimCar.java:
package decorator03;
public class SwimCar implements Car{
@Override
public void show() {
this.run();
this.swim();
}
@Override
public void run() {
System.out.println("可以跑");
}
public void swim(){
System.out.println("可以游");
}
}
这样的话我们就可以根据需求来调用了,例如我们需要一辆会飞的车:
package decorator03;
public class MainClass {
public static void main(String[] args) {
Car flycar = new FlyCar();
flycar.show();
}
}
好了,问题感觉应该完美的解决了,但是这个时候我们希望造一辆会钻地的 车,该怎么办呢?同学会说,简单啊,再创建一个会钻地的Car呀。可我们换一个角度来考虑一下,每当我们要更换一辆车的功能的时候,我们都得重新的创造一辆车,成本不是很大吗?如果此时我们能够纯粹的只造一个翅膀,只造一个潜水装置,只造一个轮子,而不是重新造一辆车,这样的话我们只需要把我们之前造的具体部件安装到最原始的车上,岂不是要方便很多呢?就好像我们最初所举的变形金刚的例子。
好了,有了这种思想,我们就进入到我们的装饰者模式。
我们先创建一个装饰者的父类:
package decorator06;
public abstract class CarDecorator implements Car{
private Car car;
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public CarDecorator(Car car){
this.car = car;
}
public abstract void show();
}
注意,这里CarDecorator.java实现了Car接口,至于为什么,请留着这个疑问看到最后。
然后我们造一个翅膀吧
package decorator06;
public class FlyCarDecorator extends CarDecorator {
public FlyCarDecorator(Car car) {
super(car);
}
@Override
public void show() {
this.getCar().show();
this.fly();
}
public void fly(){
System.out.println("可以飞");
}
@Override
public void run() {
// TODO Auto-generated method stub
}
}
接着造潜水装置吧
package decorator06;
public class SwimCarDecorator extends CarDecorator {
public SwimCarDecorator(Car car) {
super(car);
}
@Override
public void show() {
this.getCar().show();
this.swim();
}
public void swim(){
System.out.println("可以游");
}
@Override
public void run() {
}
}
那啥,貌似车本来就会跑,所以轮子我们就不造了,直接给个轮子吧
package decorator06;
public class RunCar implements Car {
@Override
public void show() {
this.run();
}
public void run(){
System.out.println("可以跑");
}
}
好了,我们先捋一捋关系,RunCar.java跟SwimCarDecorator.java和FlyCarDecorator.java有着共同的父类Car.java因为SwimCarDecorator.java和FlyCarDecorator.java继承了CarDecorator.java,而CarDecorator.java实现了Car.java接口。
好了,下面我们可以随意的改装车了
package decorator06;
public class MainClass {
public static void main(String[] args) {
Car runCar = new RunCar();
CarDecorator swimCarDecorator = new SwimCarDecorator(runCar);
CarDecorator flyCarDecorator = new FlyCarDecorator(swimCarDecorator);
flyCarDecorator.show();
}
}
你看,一辆又会飞,又会游,又会跑的车就这么华丽丽的造出来了,很激动有木有~