java建造者模式实例_Java设计模式之建造者模式

概论

什么是建造者模式呢?将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式示例

我们先来回忆一下在模板模式中的 示例,[内外部系统交互]中的四个步骤:

第一步:参数校验

第二步:封装对外的请求参数

第三步:对外提交请求

第四步:后置处理,例如记录操作日志

最后核心的算法设计在run方法中。如下代码所示:

1 public voidrun (ExampleContext context) {2

3 validate(context);4

5 prepare(context);6

7 proccess(context);8

9 after(context);10 }

客户端只要取调用run方法就可以。一切看来都很美好,但是如果我们想要把第一步和第二步交换执行顺序。或者把第二步舍弃。或者第三步和第四步交换执行顺序等等。

简单的描述一下问题:我们想要在一个算法中若干个步骤,客户端需要自定义步骤的顺序以及确定是否采用或者舍弃一些步骤。

此时需要用到建造者模式。首先我们需要有抽象产品类:

1 public abstract classAbstractProccessor {2

3 private List sequence = new ArrayList();4

5

6

7 public booleanvalidate(ExampleContext context) {8 if (context == null) {9 return false;10 }11

12 return true;13 }14

15 public abstract voidprepare(ExampleContext context);16

17 public abstract voidproccess(ExampleContext context);18

19 public abstract voidafter(ExampleContext context);20

21 protected booleanneedAfterProccessing () {22 return true;23 }24

25

26 public ListgetSequence() {27 returnsequence;28 }29

30 public void setSequence(Listsequence) {31 this.sequence =sequence;32 }33

34 public voidrun (ExampleContext context) {35

36 for(String methodName : sequence) {37 if(StringUtils.isEmpty(methodName)) {38 continue;39 }40

41 Method method = null;42

43 try{44 method = this.getClass().getMethod(methodName, ExampleContext.class);45 } catch(Exception e) {46

47 }48

49 if(method == null) {50 continue;51 }52

53 try{54 method.invoke(this, context);55 } catch(Exception e) {56

57 }58

59

60 }61 }62

63 }

第3行:声明一个表示顺序的集合,集合中存储的是算法中每个步骤的方法名。类型为String类型。

第31行-61行:run方法通过遍历顺序集合的方式依次执行。通过反射的方式来调用。

接下来,和模板方法中的两个具体产品类完全一样,一个是HttpProccessor,另外一个是OtherProccessor。代码如下所示:

1 public class HttpProccessor extendsAbstractProccessor {2

3 protected boolean needAfterProccessing = false;4

5 @Override6 public voidprepare(ExampleContext context) {7

8 System.out.println("http 前置处理");9

10 }11

12 @Override13 public voidproccess(ExampleContext context) {14

15 System.out.println("http 提交请求");16

17 }18

19 @Override20 public voidafter(ExampleContext context) {21

22 System.out.println("http 后置处理");23

24 }25

26 }

1 public class OtherProccessor extendsAbstractProccessor {2

3 @Override4 public voidprepare(ExampleContext context) {5

6 System.out.println("other 前置处理");7

8 }9

10 @Override11 public voidproccess(ExampleContext context) {12

13 System.out.println("other 提交请求");14

15 }16

17 @Override18 public voidafter(ExampleContext context) {19

20 System.out.println("other 后置处理");21

22 }23 }

最后我们需要修改一下我们的场景类Client:

1 public classClient {2

3 public static voidmain(String[] args) {4

5 AbstractProccessor proccessor = newHttpProccessor();6

7 List list = new ArrayList();8 list.add("prepare");9 list.add("proccess");10 proccessor.setSequence(list);11

12 proccessor.run(newExampleContext());13

14

15 }16 }

第7行-10行:设置要执行的步骤以及顺序。

运行结果如下所示:

http 前置处理

http 提交请求

当我们需要很多种场景,是不是需要去写很多种负责的场景类?在建造者设计模式中引入一个很重要的角色--建造者。场景类需要什么顺序,只需要告诉建造者就行。

我们新增一个建造者抽象类AbtractorBuilder。

1 public abstract classAbstractBuilder {2

3 public abstract void setSequence(Listlist);4

5 public abstractAbstractProccessor getProccessor();6 }

再新增一个HttpBuilder和OtherBuilder

public class HttpBuilder extendsAbstractBuilder {private AbstractProccessor proccessor = newHttpProccessor();

@Overridepublic void setSequence(Listlist) {

proccessor.setSequence(list);

}

@OverridepublicAbstractProccessor getProccessor() {returnproccessor;

}

}

public class OtherBuilder extendsAbstractBuilder {private AbstractProccessor proccessor = newOtherProccessor();

@Overridepublic void setSequence(Listlist) {

proccessor.setSequence(list);

}

@OverridepublicAbstractProccessor getProccessor() {returnproccessor;

}

}

继续修改一下场景类:

1 public classClient {2

3 public static voidmain(String[] args) {4

5 List list = new ArrayList();6 list.add("prepare");7 list.add("proccess");8

9 HttpBuilder httpBuilder = newHttpBuilder();10 httpBuilder.setSequence(list);11

12 AbstractProccessor proccessor =httpBuilder.getProccessor();13 proccessor.run(newExampleContext());14

15 }16 }

但是我们的HttpBuilder还是在场景类中调用时,顺序还是不够灵活。 这时需要产生一个导演类,将所有预知的情况 组合的情况一一列出来。如下代码所示:

1 public classDirector {2

3 private List sequence = new ArrayList();4 private AbstractBuilder httpBuilder = newHttpBuilder();5 private AbstractBuilder otherBuilder = newOtherBuilder();6

7 publicAbstractProccessor getHttpProccessorFirst() {8

9 this.sequence.clear();10 sequence.add("prepare");11

12 httpBuilder.setSequence(sequence);13

14 AbstractProccessor proccessor =httpBuilder.getProccessor();15

16 returnproccessor;17 }18

19 publicAbstractProccessor getHttpProccessorSecond() {20

21 this.sequence.clear();22 sequence.add("prepare");23 sequence.add("after");24

25 httpBuilder.setSequence(sequence);26

27 AbstractProccessor proccessor =httpBuilder.getProccessor();28

29 returnproccessor;30 }31

32 publicAbstractProccessor getOtherProccessorFirst() {33

34 this.sequence.clear();35 sequence.add("prepare");36

37 otherBuilder.setSequence(sequence);38

39 AbstractProccessor proccessor =otherBuilder.getProccessor();40

41 returnproccessor;42 }43

44 publicAbstractProccessor getOtherProccessorSecond() {45

46 this.sequence.clear();47 sequence.add("prepare");48 sequence.add("after");49

50 otherBuilder.setSequence(sequence);51

52 AbstractProccessor proccessor =otherBuilder.getProccessor();53

54 returnproccessor;55 }56 }

最后我们在修改一下场景类:

1 public classClient {2

3 public static voidmain(String[] args) {4

5 AbstractProccessor proccessor = null;6

7 Director director = newDirector();8 proccessor =director.getHttpProccessorFirst();9 proccessor.run(newExampleContext());10

11 proccessor =director.getHttpProccessorSecond();12 proccessor.run(newExampleContext());13

14

15 proccessor =director.getOtherProccessorFirst();16 proccessor.run(newExampleContext());17

18 proccessor =director.getOtherProccessorSecond();19 proccessor.run(newExampleContext());20

21

22

23 }24 }

简单而明了,笔者在开发的过程中,遇到很多的开发者不注意代码质量,甚至连资深的技术专家都没有意识到这一点。写下一行代码需要10秒钟,而看懂一行代码确实需要很大的力气。因此设计模式是用简单的方式将复杂的业务需求清晰的表达出来。

最后总结一下。建造者模式是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

在建造者模式中有4个角色,分别是产品类,抽象建造者,具体建造者,导演。

建造者模式的优点

1.良好的封装:场景类不必知道产品内部的细节。

2.建造者的独立,良好的扩展:存在不同的具体建造者,每个建造者之间独立。

3.良好的控制风险:因为具体的建造者是相互独立的,因此建造过程也是独立的,不会某一个建造者的变动对其他造成影响。

你可能感兴趣的:(java建造者模式实例)