用最简单的例子说明设计模式(三)之责任链、建造者、适配器、代理模式、享元模式...

责任链模式
一个请求有多个对象来处理,这些对象是一条链,但具体由哪个对象来处理,根据条件判断来确定,如果不能处理会传递给该链中的下一个对象,直到有对象处理它为止
使用场景
1)有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定
2)在不明确指定接收者的情况下,向多个对象中的一个提交一个请求
3)可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求
public class Chain {public abstract class Handler {private Handler nextHandler;// 当前领导能审批通过的最多天数public int maxDay;protected Handler(int maxDay) {this.maxDay = maxDay;}//设置责任链中下一个处理请求的对象public void setNextHandler(Handler handler) {nextHandler = handler;}protected void handleRequest(int day) {if (day <= maxDay) {reply(day);} else {if (nextHandler != null) {//审批权限不够,继续上报nextHandler.handleRequest(day);} else {System.out.println("没有更高的领导审批了");}}}protected abstract void reply(int day);}class ProjectManager extends Handler {public ProjectManager(int day) {super(day);}@Overrideprotected void reply(int day) {System.out.println(day + "天请假,项目经理直接审批通过");}}class DepartmentManager extends Handler {public DepartmentManager(int day) {super(day);}@Overrideprotected void reply(int day) {System.out.println(day + "天请假,部门经理审批通过");}}class GeneralManager extends Handler {public GeneralManager(int day) {super(day);}@Overrideprotected void reply(int day) {System.out.println(day + "天请假,总经理直接审批通过");}}public static void main(String[] strings) {Chain chain = new Chain();Handler projectManager = chain.new ProjectManager(3);Handler departmentManager = chain.new DepartmentManager(5);Handler generalManager = chain.new GeneralManager(15);//创建职责链projectManager.setNextHandler(departmentManager);departmentManager.setNextHandler(generalManager);//发起请假请求projectManager.handleRequest(4);}
}

  

Buidler(建造者)模式
一种创建型的设计模式.,通常用来将一个复杂的对象的构造过程分离, 让使用者可以根据需要选择创建过程.另外, 当这个复杂的对象的构造包含很多可选参数时, 也可以使用建造者模式
public class AlerDialog {private  String title;private  String message;public AlerDialog(Builder builder) {
//        View.inflate()this.title = builder.title;this.message = builder.message;}public static class Builder {private  String title;private  String message;public  Builder setTitle(String title) {this.title = title;return this;}public   Builder setMessage(String message) {this.message = message;return this;}public  AlerDialog build() {return new AlerDialog(this);}}
}new AlerDialog.Builder().setTitle("").setMessage("").build();

  

 

适配器模式:
把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起使用的类能够一起工作。  
适配器就是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配,简单点理解就是平常所见的转接头,转换器之类的存在。

 


类适配器
原理:通过继承来实现适配器功能。
类适配器使用对象继承的方式,是静态的定义方式 
对于类适配器,适配器可以重定义Adaptee的部分行为,使Adaptee有了sampleOperation2()
对于类适配器,仅仅引入了一个对象,并不需要额外的引用来间接得 到 Adaptee 
对于类适配器,由于适配器直接继承了Adaptee,使得适配器不能和 Adaptee的子类一起工作 
public interface Target {void sampleOperation1();void sampleOperation2();
}
public class Adaptee {public void sampleOperation1() {System.out.println("sampleOperation1");}
}
public class Adapter extends Adaptee implements Target {@Overridepublic void sampleOperation2() {System.out.println("sampleOperation2");}}
public class MyClass {public static void main(String[] args) {Adapter adapter = new Adapter();adapter.sampleOperation1();adapter.sampleOperation2();}
}

  


对象适配器
与类的适配器模式一样,对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。
对象适配器使用对象组合的方式,是动态组合的方式
对于对象适配器,一个适配器(adaptee)可以把多种不同的源适配到同一个目标
对于对象适配器,要重定义Adaptee的行为比较困难
对于对象适配器,需要额外的引用来间接得到Adaptee。
public interface Target {void sampleOperation1();void sampleOperation2();
}public class Adaptee {public void sampleOperation1() {System.out.println("sampleOperation1");}
}public class Adapter implements Target {private Adaptee mAdaptee;public Adapter(Adaptee adaptee) {mAdaptee = adaptee;}@Overridepublic void sampleOperation1() {mAdaptee.sampleOperation1();}@Overridepublic void sampleOperation2() {System.out.println("sampleOperation2");}}public class MyClass {public static void main(String[] args) {Adapter adapter =new Adapter(new Adaptee());adapter.sampleOperation1();adapter.sampleOperation2();}
}

  

 
代理模式
通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,扩展目标对象的功能。在调用这个方法前作的前置处理(统一的流程代码放到代理中处理)。调用这个方法后做后置处理。
这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法。
动态代理的用途与装饰模式很相似,就是为了对某个对象进行增强。所有使用装饰者模式的案例都可以使用动态代理来替换。
/*** subject(抽象主题角色):* 真实主题与代理主题的共同接口。*/
interface Subject {void sellBook();
}/*** ReaISubject(真实主题角色):* 定义了代理角色所代表的真实对象。*/
public class RealSubject implements Subject {@Overridepublic void sellBook() {System.out.println("出版社卖书");}
}/*** Proxy(代理主题角色):* 含有对真实主题角色的引用,代理角色通常在将客* 户端调用传递给真实主题对象之前或者之后执行某些* 操作,而不是单纯返回真实的对象。*/
public class ProxySubject implements Subject {private RealSubject realSubject;@Overridepublic void sellBook() {if (realSubject == null) {realSubject = new RealSubject();}sale();realSubject.sellBook();give();}public void sale() {System.out.println("打折");}public void give() {System.out.println("送优惠券");}
}public class Main {public static void main(String[] args) {//静态代理(我们自己静态定义的代理类)ProxySubject proxySubject = new ProxySubject();proxySubject.sellBook();//动态代理(通过程序动态生成代理类,该代理类不是我们自己定义的。而是由程序自动生成)RealSubject realSubject = new RealSubject();MyHandler myHandler = new MyHandler();myHandler.setProxySubject(realSubject);Subject subject = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),realSubject.getClass().getInterfaces(), myHandler);subject.sellBook();}
}public class MyHandler implements InvocationHandler {private RealSubject realSubject;public void setProxySubject(RealSubject realSubject) {this.realSubject = realSubject;}/*** @param proxy   指代我们所代理的那个真实对象* @param method   指代的是我们所要调用真实对象的某个方法的Method对象* @param args    指代的是调用真实对象某个方法时接受的参数* @return* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {sale();proxy = method.invoke(realSubject, args);give();return proxy;}public void sale() {System.out.println("打折");}public void give() {System.out.println("送优惠券");}
}

  

享元模式
享元的目的是为了减少不会要额内存消耗,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗。
public class FlyWeight {static class MyString {private String myChar;public MyString(String myChar) {this.myChar = myChar;}public void display() {System.out.println(myChar);}}static class MyCharacterFactory {private Map<String, MyString> pool;public MyCharacterFactory() {pool = new HashMap<>();}public MyString getMyCharacte(String strig) {MyString myString = pool.get(strig);if (myString == null) {myString = new MyString(strig);pool.put(strig, myString);}return myString;}}public static void main(String[] args) {MyCharacterFactory myCharacterFactory = new MyCharacterFactory();MyString a = myCharacterFactory.getMyCharacte("a");MyString b = myCharacterFactory.getMyCharacte("b");MyString a1 = myCharacterFactory.getMyCharacte("a");MyString d = myCharacterFactory.getMyCharacte("d");if (a == a1) {System.out.println("true");}}
}

  

相关源码:https://github.com/peiniwan/DesignPattern.git

转载于:https://www.cnblogs.com/sixrain/p/9021641.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/398004.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用Java针对MySql封装的jdbc框架类 JdbcUtils 完整实现(包含增删改查、JavaBean反射原理,附源码)...

最近看老罗的视频&#xff0c;跟着完成了利用Java操作MySQL数据库的一个框架类JdbcUtils.java,完成对数据库的增删改查。其中查询这块&#xff0c;包括普通的查询和利用反射完成的查询&#xff0c;主要包括以下几个函数接口: 1、public Connection getConnection() 获得数据库…

Linux启动提示Kernel panic - not syncing: Attempted to kill init解决办法

系统类型&#xff1a;CentOS 6.5(x64) 启动提示&#xff1a;Kernel panic - not syncing: Attempted to kill init 解决办法&#xff1a; 系统启动的时候&#xff0c;按下‘e’键进入grub编辑界面&#xff0c;编辑grub菜单&#xff0c;选择“kernel /vmlinuz-XXXXro root/dev/v…

vuex和vuejs

前言&#xff1a;在最近学习 Vue.js 的时候&#xff0c;看到国外一篇讲述了如何使用 Vue.js 和 Vuex 来构建一个简单笔记的单页应用的文章。感觉收获挺多&#xff0c;自己在它的例子的基础上进行了一些优化和自定义功能&#xff0c;在这里和大家分享下学习心得。 在这篇教程中我…

laravel mysql 配置,laravel5数据库配置及其注意事项

今天分享一个Laravel5数据库配置上的坑。Laravel5作为一套简洁、优雅的PHP Web开发框架(笑)&#xff0c;唯一不足的一点就是中文手册或者说是资料比较少&#xff0c;虽然现在很多大神也开始普及这些东西&#xff0c;但是大神一遍也会忽略一下小坑。今天配置了一下数据库&#x…

React开发中常用的工具集锦

本文从属于笔者的React入门与最佳实践系列。本文记录了笔者在React开发中常见的一些工具插件&#xff0c;如果你想寻找合适的项目生成器或者模板&#xff0c;请参考笔者的使用Facebook的create-react-app快速构建React开发环境 React Devtools React Devtools是React官方提供的…

9-[记录操作]--数据的增删改,权限管理

1、数据操作语言&#xff1a; DML&#xff08;data manage language&#xff09; 在MySQL管理软件中&#xff0c;可以通过SQL语句中的DML语言来实现数据的操作&#xff0c;包括 使用INSERT实现数据的插入UPDATE实现数据的更新使用DELETE实现数据的删除使用SELECT查询数据以及。…

hdu 1023 Train Problem II

题目连接 http://acm.hdu.edu.cn/showproblem.php?pid1212 Train Problem II Description As we all know the Train Problem I, the boss of the Ignatius Train Station want to know if all the trains come in strict-increasing order, how many orders that all the tra…

Nginx自建CDN加速节点 实现DNS智能解析网站项目

如今&#xff0c;网站项目越来越多的会使用CDN加速&#xff0c;如果需要便捷一点的可以直接用第三方提供的CDN加速服务&#xff0c;比如百度CDN、七牛、又拍云、腾讯云、阿里云等等服务商都有提供这类服务。但是前提条件是需要一定的成本&#xff0c;以及网站域名是需要BA才可以…

matlab中获取view,ios 怎么获取一个view的位置

ios 怎么获取一个view的位置以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;ios 怎么获取一个view的位置打开appstore进入应用&#xff0c;右上角的分享按钮(从右往左数第二个)&#xff0c;拷…

eureka需要替换吗_Spring Cloud Alibaba迁移指南1:零代码从Eureka迁移到Nacos

作者&#xff1a;得少&#xff0c;校对&#xff1a;周立。在本号首发&#xff0c;欢迎转载。Spring Cloud官方宣布Spring Cloud Netflix进入维护状态&#xff0c;后续不再会有新的功能已成为事实。作为开发者&#xff0c;如何使用极简的方式替换Netflix相关组件成为首要解决的问…

JAVA TCP通信练习

2019独角兽企业重金招聘Python工程师标准>>> 1、Server端 package com.hhdys.serviceimpl;import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.…

微服务架构下的身份认证

从单体应用架构到分布式应用架构再到微服务架构&#xff0c;应用的安全访问在不断的经受考验。为了适应架构的变化、需求的变化&#xff0c;身份认证与鉴权方案也在不断的变革。面对数十个甚至上百个微服务之间的调用&#xff0c;如何保证高效安全的身份认证&#xff1f;面对外…

php缓存注入,利用Thinkphp 5缓存漏洞实现前台Getshell

原标题&#xff1a;利用Thinkphp 5缓存漏洞实现前台Getshell*本文原创作者&#xff1a;WindWing&#xff0c;属于FreeBuf原创奖励计划&#xff0c;禁止转载000 背景网站为了实现加速访问&#xff0c;会将用户访问过的页面存入缓存来减小数据库查询的开销。而Thinkphp5框架的缓存…

mac版小达人点读包怎么安装_小达人点读笔扩容实战:16G变128G

随着小达人点读笔可以点读的童书越来越多&#xff0c;笔的容量就是个尴尬的问题&#xff1a;是处理掉手头的16G容量的旧点读笔&#xff0c;重新再买32G容量的新点记笔吗&#xff1f;如果32G容量也不够用怎么办&#xff1f;官方可没有更大容量的点读笔了。删除原先的点读内容&am…

WorldWind源码剖析系列:可渲染对象类RenderableObject

RenderableObject是WorldWind中所有需要渲染的对象的父类&#xff0c;继承了接口IRenderable和Icomparable。其派生类体系如下所示。RenderableObject的成员如下所示。 RenderableObjectList也继承自RenderableObject。 接口Irenderable内部仅仅定义下面三个接口&#xff0c;分…

php table 下拉框,LayerUI的table 里面加 select 下拉框 – Fly社区-Mikel

先上效果图&#xff1a;直接上代码//添加样式&#xff1a;.table-select-icon{position:absolute;right:10px;line-height:34px;color:#d3d3d3}.table-select-selected dl{display:block}.table-select dl{position:absolute;left:0;padding:5px 0;z-index:999;min-width:100%;…

家里wifi网速越来越慢_家里的wifi信号不好?有了它再也不怕网速慢啦

夏天太热&#xff0c;就想宅在家里刷刷剧、打打游戏、看看新闻。可是网速却不好&#xff0c;看一会儿&#xff0c;卡一会儿&#xff0c;本来天气就热&#xff0c;这样更加烦躁&#xff01;这WiFi信号怎么会这么差&#xff1f;有什么好办法能解决这个问题呢&#xff1f;只要有了…

python文件操作实验总结,[干货分享]Python文件操作技巧总结

引言小伙伴们&#xff0c;今天给大家讲解一下python程序下的文件操作完整技巧梳理&#xff0c;都是笔者总结的干货。通过本文阅读&#xff0c;不仅可以带来生产力提升&#xff0c;也可以开发小脚本为生活带来乐趣。首先不知道大家对python有没有了解&#xff0c;不太会用的小伙…

7价 半导体掺杂_天津大学封伟团队:新型半导体二维原子晶体锗硅烷材料的带隙调控...

xxxxxxxxxxxx【研究背景】xxxx新型二维半导体原子晶体兼具原子级厚度、纳米级层状结构、极高的载流子迁移率&#xff0c;是构建未来高性能纳米光电器件的核心材料。带隙是二维半导体电子器件和光电子光器件中最重要的基本参数之一&#xff0c;是影响二维半导体电子器件开关比和…