原型模式简单介绍【设计模式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 //在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 }
前情回顾1是原有代码,前情回顾2是后来代码略作修改,将middlewarecenter进行了分割,middlewarecenter只保存核心,middlewarecenterhelper是通过middlewarecenter的帮助类。
middlewarecenterhelper中现在实现俩个类:use(将handler加入到责任链中),run(将handler加入责任链中,并且后面的进行短路不再执行)。现在想要加入when方法,使when方法部分的handler能够根据条件(config)动态决定是否执行。
when方法
when方法有俩个地方需要注意:
- when中可能是一个handler也可能是handler数组,甚至可能是imiddlerware对象。
- 判断是否能够执行,是运行过程中的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深复制有什么注意的呢
下节请继续看往祖坟上刨根问底的原型模式