设计模式----建造者模式
创建型模式
建造者模式:又叫生成器模式,就是对流程的抽象,一步一步的去创建一个复杂的对象。
举个实例,有一个化学老师需要在公开课上向校长等人演示摸个试管实验,老师请了两个同学A和B上台演示,AB的操作顺序都是一样的,只是试剂所放的量不一样而已,那么老师要如何控制这个学生呢?如果我们只是简单地定义两个学生类A和B的话,由于两个人的实验顺序(方法)是一样的,那么就很容易出错,搞错了顺序?或者漏掉某个步骤?
解决:因为他们具有一样的组成成分,那么就可以让他们同时继承一个抽象接口,该接口提供他们所需要的步骤,以确保不会漏掉某步。因为子类必须实现抽象接口里的所有方法。
抽象接口类:
1
2
3
4
5
|
public abstract class Student { public abstract void buZou1(); public abstract void buZou2(); public abstract void buZou3(); } |
学生A:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class StudentA extends Student{ @Override public void buZou1() { System.out.println( "AAAAA" ); } @Override public void buZou2() { System.out.println( "BBBBBB" ); } @Override public void buZou3() { System.out.println( "CCCCCC" ); } } |
学生B:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class StudentB extends Student{ @Override public void buZou1() { System.out.println( "OOOOO" ); } @Override public void buZou2() { System.out.println( "PPPPP" ); } @Override public void buZou3() { System.out.println( "QQQQQQ" ); } } |
虽然保证了不会漏掉某部,但是还是无法保证学生能正确操作?这是就可以使用建造者模式,有老师来控制。
teacher类:
1
2
3
4
5
6
7
8
9
10
11
|
public class Teacher { private Student student; public Teacher(Student student) { this .student = student; } public void DirectEx() { student.buZou1(); student.buZou2(); student.buZou3(); } } |
主函数:
1
2
3
4
5
6
7
8
|
public static void main(String args[]) { Student studentA = new StudentA(); Student studentB = new StudentB(); Teacher teacher = new Teacher(studentA); teacher.DirectEx(); teacher = new Teacher(studentB); teacher.DirectEx(); } |
总结:建造者模式就是当需要一个复杂对象的构建或者造作过程和这个对象的表示相分离,就可以使用了。就相当于A和 B是具体的创建者,知道怎么操作,但是学生不知道完成一次实验需要按照何种步骤来进行,而老师作为指挥者,了解实验步骤,可以指挥学生(按一定顺序调用学生类提供的方法)来实验,客户端就只需要关心结果就好了。使用这个模式,用户只要制定要创建的类型就可以得到对应的对象,为具体的过程被direct和builder影藏了。而这正体现了依赖倒转的原则,抽象不依赖于细节,细节依赖于抽象。
建造者模式的标准代码:
Builder:
1
2
3
4
5
|
public abstract class Builder { public abstract void builderPartA(); public abstract void builderPartB(); public abstract Product getResult(); } |
product:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class Product { ArrayList<String> parts = new ArrayList<String>(); public void add(String part) { parts.add(part); } public void show() { System.out.println( "create product" ); for ( int i = 0 ; i < parts.size(); i++) { String part = parts.get(i) ; System.out.println(part); } } } |
建造者类A:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class ConcreteBuilderA extends Builder{ private Product product = new Product(); @Override public void builderPartA() { product.add( "part A" ); } @Override public void builderPartB() { product.add( "part B" ); } @Override public Product getResult() { return product; } } |
建造者B:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class ConcreteBuilderB extends Builder{ private Product product = new Product(); @Override public void builderPartA() { product.add( "part W" ); } @Override public void builderPartB() { product.add( "part Q" ); } @Override public Product getResult() { return product; } } |
指挥者:这里控制之行动的顺序
1
2
3
4
5
6
|
public class Director { public void construct(Builder builder){ builder.builderPartA(); builder.builderPartB(); } } |
客户端:
1
2
3
4
5
6
7
8
9
10
11
12
|
public static void main(String args[]) { Director director = new Director(); Builder builder = new ConcreteBuilderA(); Builder builder2 = new ConcreteBuilderB(); director.construct(builder); Product productA = builder.getResult(); productA.show(); director.construct(builder2); Product productB = builder2.getResult(); productB.show(); } |
建造者优点:
1)在建造者模式中,客户端不必知道产品内部组成的具体细节,将产品本身于产品的创建过程进行解耦,是的相同的创建过程可以创建不同的产品对象。
2)每一个具体的建造者都是独立的,而与其他的具体建造者没有关系,可以很方便的去增加或者删除一个建造者,用户用不同的建造者就可以获得不同的产品。
3)可以更加精细的控制产品创建的具体过程,将复杂的产品步骤分解在不同的方法当中,是的创建过程更加清晰。
4)增加新的建造者不用修改原有类库的代码,指挥者类是针对抽象建造者类编写的,扩展方便,符合开放封闭原则。