欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-08-31 16:47:16
前文回顾: 1 //上下文 2 public class Context { 3 public String getHandlerResult() { 4 return handlerResult; 5 } 6 7 public void setHandlerResult(String handle ......

前文回顾

原型模式简单介绍【设计模式3】
 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
原型模式简单介绍【设计模式3】
 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深复制有什么注意的呢

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