Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

原型模式简单介绍【设计模式3】

码对象 2019-02-20 11:45:00 阅读数:135 评论数:0 点赞数:0 收藏数:0

前文回顾

 1 //上下文
 2 public class Context {
 3 public String getHandlerResult() {
 4 return handlerResult;
 5  }
 6
 7 public void setHandlerResult(String handlerResult) {
 8 this.handlerResult = handlerResult;
 9  }
10
11 private String handlerResult;
12 }
13 //Handler接口
14 public interface IHandler {
15 void handler(Context context);
16 }
17 //NullHandler 
18 public class NullHandler implements IHandler {
19  @Override
20 public void handler(Context context) {
21
22  }
23 }
24 //Middleware接口
25 public interface IMiddleware {
26  IHandler handle(IHandler handler);
27 }
28 //MiddlewareCenter核心代码
29 public class MiddlewareCenter implements Cloneable {
30 private ArrayList<IMiddleware> middlewares = new ArrayList<>();
31
32 public void userMiddleware(IMiddleware middleware) {
33  middlewares.add(middleware);
34  }
35
36 public IHandler build() {
37 IHandler handler = new NullHandler();
38  Collections.reverse(middlewares);
39 for (IMiddleware middlerware : middlewares) {
40 handler = middlerware.handle(handler);
41  }
42 return handler;
43  }
44
45  @Override
46 protected Object clone() throws CloneNotSupportedException {
47 MiddlewareCenter middlewareCenter = new MiddlewareCenter();
48 middlewareCenter.middlewares.addAll(this.middlewares);
49 return middlewareCenter;
50  }
51 }
前情回顾1
 1 //在MiddlewareCenter中的部分,提取出来放到helper类里
 2 public class MiddlewareCenterHelper {
 3 public static MiddlewareCenter use(MiddlewareCenter middlewareCenter, IHandler handler) {
 4 middlewareCenter.userMiddleware(currenthandler -> {
 5 return context -> {
 6  handler.handler(context);
 7  currenthandler.handler(context);
 8  };
 9  });
10 return middlewareCenter;
11  }
12
13 public static void run(MiddlewareCenter middlewareCenter, IHandler handler) {
14 middlewareCenter.userMiddleware(currenthandler -> {
15 return context -> {
16  handler.handler(context);
17  };
18  });
19  }
20 }
前情回顾2

前情回顾1是原有代码,前情回顾2是后来代码略作修改,将MiddleWareCenter进行了分割,MiddleWareCenter只保存核心,MiddleWareCenterHelper是通过MiddleWareCenter的帮助类。

MiddleWareCenterHelper中现在实现俩个类:use(将handler加入到责任链中),run(将handler加入责任链中,并且后面的进行短路不再执行)。现在想要加入when方法,使when方法部分的handler能够根据条件(Config)动态决定是否执行。

when方法

when方法有俩个地方需要注意:

  1. when中可能是一个handler也可能是handler数组,甚至可能是IMiddlerWare对象。
  2. 判断是否能够执行,是运行过程中的config对象,不是初始的config对象

下面就是when方法的实现:

 1 public class MiddlewareCenterHelper {
 2 public static MiddlewareCenter use(MiddlewareCenter middlewareCenter, IHandler handler) {
 3 //
 4  }
 5
 6 public static void run(MiddlewareCenter middlewareCenter, IHandler handler) {
 7 //
 8  }
 9
10 public static MiddlewareCenter when(MiddlewareCenter middlewareCenter, Consumer<MiddlewareCenter> config, Predicate<Context> predicate) {
11 try {
12 MiddlewareCenter center = (MiddlewareCenter) middlewareCenter.clone();
13  config.accept(center);
14 middlewareCenter.userMiddleware(main -> {
15 IHandler branch = center.build();
16 return context -> {
17 if (predicate.test(context)) {
18  branch.handler(context);
19 } else {
20  main.handler(context);
21  }
22  };
23  });
24 } catch (CloneNotSupportedException ex) {
25
26  }
27 return middlewareCenter;
28  }
29 }

 when方法中,配置参数使用Consumer<T>,这是一个妙笔,在需要对对象进行配置的时候建议使用这个参数。

在when中,我们看见MiddlewareCenter center = (MiddlewareCenter) middlewareCenter.clone();这就是原型模式的典型写法(至于此处为什么不new MiddlewareCenter(),而要clone一个,如果new会导致责任链断裂,在when后面加入的handler不会被执行,具体解释略)。原型模式区别于直接new对象的地方在于,原型模式会保存对象内部的变量,而new原有属性都会被重置。当构造新对象的时候需要保留原有对象已经赋值的属性,就要使用原型模式。而Middleware中clone方法的实现如下所示:

 

1 public class MiddlewareCenter implements Cloneable {
2 //其他略
3  @Override
4 protected Object clone() throws CloneNotSupportedException {
5 MiddlewareCenter middlewareCenter = new MiddlewareCenter();
6 middlewareCenter.middlewares.addAll(this.middlewares);
7 return middlewareCenter;
8  }
9 }

 

总结

原型模式只是简单实现一个clone方法(当然你也可以起名叫copy、getInstance等),在需要的时候对现有对象进行复制。但是在java上原型模式真的这么简单吗?

答案是否定的,在java上这点可以扩展很多内容。

1,构建对象有多少种方式呢?clone、new新对象还有别的吗?

2,clone为啥要实现Cloneable,我直接起名叫copy,不实现接口也不抛出异常不是更好吗?

3,什么是深复制,什么是浅复制

4,serializable深复制有什么注意的呢

下节请继续看往祖坟上刨根问底的原型模式

 

版权声明
本文为[码对象]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/SharePointApp/p/10405284.html

编程之旅,人生之路,不止于编程,还有诗和远方。
阅代码原理,看框架知识,学企业实践;
赏诗词,读日记,踏人生之路,观世界之行;

支付宝红包,每日可领