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

2019-02-21 06:39:09来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

前文回顾

 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
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Activiti(二) springBoot2集成activiti,集成activiti在线设计

下一篇:RabbitMQ是如何运转的?