设计模式--装饰者模式和建造者模式
1. 装饰者模式
动态地给一个对象添加一些额外的职责。就增加功能来说, Decorator模式相比生成子类更为灵活,而且能解决继承子类爆炸问题。
参与者
1.Component(被装饰对象的基类)
定义一个对象接口,可以给这些对象动态地添加职责。
2.ConcreteComponent(具体被装饰对象)
定义一个对象,可以给这个对象添加一些职责。
3.Decorator(装饰者抽象类)
维持一个指向Component实例的引用,并定义一个与Component接口一致的接口。
4.ConcreteDecorator(具体装饰者)
具体的装饰对象,给内部持有的具体被装饰对象,增加具体的职责。
代码案例:
Component (被装饰对象的基类)
public interface Person { void eat(); }
ConcreteComponent (具体被装饰对象)
public class Man implements Person { public void eat() { System.out.println("男人在吃"); } }
Decorator (装饰者抽象类)
public abstract class Decorator implements Person { protected Person person; public void setPerson(Person person) { this.person = person; } public void eat() { person.eat(); } }
ConcreteDectrator (具体装饰者)
public class ManDecoratorA extends Decorator { public void eat() { super.eat(); reEat(); System.out.println("ManDecoratorA类"); } public void reEat() { System.out.println("再吃一顿饭"); } } public class ManDecoratorB extends Decorator { public void eat() { super.eat(); System.out.println("==============="); System.out.println("ManDecoratorB类"); } }
Test
public class Test { public static void main(String[] args) { Man man = new Man(); ManDecoratorA md1 = new ManDecoratorA(); ManDecoratorB md2 = new ManDecoratorB(); md1.setPerson(man); md2.setPerson(md1); md2.eat(); } }
2. 建造者模式
在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
举个例子:
那我们新建一个人的类。
Person类
public class Person { private String head; private String body; private String foot; public String getHead() { return head; } public void setHead(String head) { this.head = head; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getFoot() { return foot; } public void setFoot(String foot) { this.foot = foot; } @Override public String toString() { return "Person [head=" + head + ", body=" + body + ", foot=" + foot + "]"; } }
定义了造人标准的接口 PersonBuilder
public interface PersonBuilder { void buildHead(); void buildBody(); void buildFoot(); Person buildPerson(); }
既然接口都有了,我们就按照人的一些特性,建造一个机器人 Robot 吧。
public class Robot implements PersonBuilder { Person person; public Robot(){ person = new Person(); } //创建一个机器人 @Override public void buildHead() { person.setHead("机器人的头部"); System.out.println("正在构造机器人的头部"); } @Override public void buildBody() { person.setBody("身体"); System.out.println("正在构造机器人的身体"); } @Override public void buildFoot() { person.setFoot("脚"); System.out.println("正在构造机器人的脚部"); } @Override public Person buildPerson() { System.out.println("机器人构造完毕"); return person; } }
这个机器人 Robot 实现了 PersonBuilder 这个造人标准的接口了。最后返回造好的Robot。
好的,其实到这里呢,我们已经完成了建造的过程。那就这么简单的建造过程,还搞了一个建造模式吗?非也。接下来,就是介绍建造者模式的精髓,那就是director。这个director呢,就是来执行我们刚才的造人动作的。没错,精髓就是我们刚才的造人动作。我们先看代码:
Director类
public class Director { public Person createRobotByDirector(PersonBuilder pb){ pb.buildBody(); pb.buildFoot(); pb.buildHead(); return pb.buildPerson(); } }
这个director类呢,重点在于createRobotByDirecotr的参数是我们的造人标准的接口。这样一来,只要是实现了我们的这个接口的类,就都可以作为参数,我们刚刚不是造了一个高智商的人吗?那我们如果想造一个身体运动能力出色的人,也就是运动员,这个director也可以启动这个造人过程,只要我们把这个运动员的类先写好。我们来看看director是如何发挥的
public class Test { public static void main(String[] args) { Director d = new Director(); Person p = d.createRobotByDirector(new Robot()); System.out.println(p); } }
运行结果:
正在构造机器人的身体 正在构造机器人的脚部 正在构造机器人的头部 机器人构造完毕 Person [head=机器人的头部, body=身体, foot=脚]
看,createRobotByDirecotr这个方法带的参数就是我们高智商人的那个类。那我们想造一个运动员,就可以像高智商人那样建好类,然后传进来就可以了!
总结: 其实根本就不会知道具体是怎么造人的,因为这个过程让director给代劳了。故体现了:在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。