从网络上找的设计模式, 很全面,只要把UML类图看懂了, 照着类图将代码实现是很容易的事情.

步骤: 先看懂类图, 然后将代码实现, 之后再看文字

http://c.biancheng.net/design_pattern/

https://www.runoob.com/design-pattern/abstract-factory-pattern.html

7大设计原则:

1: 单一职责原则: 类应该只有一个职责,或者功能

2: 接口隔离原则: 一个类不应该依赖与他不相关,不需要的接口, 一个类对另一个类的依赖应该建立在最小的接口上

3: 依赖倒置原则: 依赖抽象不依赖具体,思想是:面向接口编程

4: 里氏替换原则: java中的继承有弊端, 少用继承, 多使用聚合,组合,依赖, 因为子类继承后,很容易不小心将父类中的方法重写, 而子类不知道,调父类方法时候,容易混淆, 换句话就是: 所有使用父类方

法的地方,也能透明的使用其子类的对象, 子类尽量不要重写父类的方法, 可以将父类和子类都继承一个更通俗的父类,

5: 开闭原则(ocp原则): 对扩展开放(提供方), 对修改关闭(使用方)

6: 迪米特原则: 最少知道原则, 一个类对自己依赖的类知道越少越好,被依赖的类尽量将逻辑都封装到类中,只提供外一个入口就好, 又叫: 只和直接朋友通信,(直接朋友:成员变量,方法入参, 方法返回

值中的类都是直接朋友, 局部变量中的类不是直接朋友, 也就是说陌生的类,不要以局部变量的方式出现在类中)

7: 合成复用原则: 尽量使用聚合,组合的方式, 少用继承, 这样做目的是 松耦合

一: 1.1:简单工厂模式(又叫静态工厂模式): 是将各种对象的创建都交给一个工厂类, client要使用各种对象时候,只需要在client中聚合这个工厂类即可,

比如这个图中,胡椒披萨,榴莲披萨,原味披萨, 都有一个共同的基类Pizza, 工厂类SimpleFactory 根据不同类型返回对应的披萨对象,, OrderPizza这个就是client类, 在OrderPizza类中聚合工厂类即可, 就可以根据不同类型创造不同口味的披萨了


1.2: 工厂方法模式: 假如有北京胡椒披萨,北京榴莲披萨,北京原味披萨, 伦敦胡椒披萨,伦敦榴莲披萨,伦敦原味披萨. 此时使用简单工厂模式是不合适的, 等于在这个工厂类中,要分别创建这6个披萨对象, 修改多,维护性,扩展性差 .解决方法: 简单工厂模式是创建了一个工厂类, 工厂方法模式,是创建一个抽象工厂类,他的实现是北京工厂类, 伦敦工厂类, 在实现类中完成对象的创建,

这样等于是,将对象的创建交给子类取实现.uml类图如下:

1.3: 抽象工厂模式: 工厂方法模式是创建了一个 抽象工厂类,让子类取实现,完成对象创建, 很相似 抽象工厂模式是定义一个接口, 对象的创建在子类中完成.client中聚合该接口类,uml类图如下

工厂模式再JDK源码中的应用

  1. Calendar date = Calendar.getInstance();
  2. public static Calendar getInstance(){
  3. return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
  4. }

再点进去

  1. private static Calendar createCalendar(TimeZone zone,Locale aLocale){
  2. CalendarProvider provider =
  3. LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
  4. .getCalendarProvider();
  5. if (provider != null) {
  6. try {
  7. return provider.getInstance(zone, aLocale);
  8. } catch (IllegalArgumentException iae) {
  9. // fall back to the default instantiation
  10. }
  11. }
  12. Calendar cal = null;
  13. if (aLocale.hasExtensions()) {
  14. //这里根据时区不同,来创建不同的对象
  15. String caltype = aLocale.getUnicodeLocaleType("ca");
  16. if (caltype != null) {
  17. switch (caltype) {
  18. case "buddhist":
  19. cal = new BuddhistCalendar(zone, aLocale);
  20. break;
  21. case "japanese":
  22. cal = new JapaneseImperialCalendar(zone, aLocale);
  23. break;
  24. case "gregory":
  25. cal = new GregorianCalendar(zone, aLocale);
  26. break;
  27. }
  28. }
  29. }
  30. if (cal == null) {
  31. // If no known calendar type is explicitly specified,
  32. // perform the traditional way to create a Calendar:
  33. // create a BuddhistCalendar for th_TH locale,
  34. // a JapaneseImperialCalendar for ja_JP_JP locale, or
  35. // a GregorianCalendar for any other locales.
  36. // NOTE: The language, country and variant strings are interned.
  37. if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
  38. cal = new BuddhistCalendar(zone, aLocale);
  39. } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
  40. && aLocale.getCountry() == "JP") {
  41. cal = new JapaneseImperialCalendar(zone, aLocale);
  42. } else {
  43. cal = new GregorianCalendar(zone, aLocale);
  44. }
  45. }
  46. return cal;
  47. }

二: 原型模式: 原型模式就是将一个对象复制出另一个对象来,除了内存地址不同,其余都相同, 使用Object类中的clone方法, 如果一个对象中的属性都是基本数据类型, 使用clone方法就可以实现对象的复制, 如果该对象中的属性,有引用数据类型(数组,另一个对象,list,)此时使用clone方法,不能实现对象的完全复制, 因为 引用数据类型,使用clone方法,在内存中只是指针的引用,并没有重新复制出相同的对象来,,,, 建议使用流序列化的方式实现深拷贝

原型模式在spring中的应用, spring中的bean的创建, xml文件中配置 这里的 scope="prototype"就是指对象多例模式, 其实就是原型模式,复制一模一样的对象

三: 建造者模式: 将复杂对象的建造过程 抽象出来, 从而他的实现类可以构造出不同属性的对象, 用户只需要指定复杂对象的类型和内容,就可以建造他们,不需要知道具体的建造过程. 比如房子建造过程: 打地基,砌墙,封顶, 他的实现类:普通房子实现类, 创建的对象:普通房子,地基150cm,墙厚15cm,顶是茅草顶, 另一个实现类:豪宅,创建的对象: 地基300cm,墙厚50cm,顶是金砖顶.

有四个角色:

1:产品(product)

2:抽象建造者(builder), 创建一个product对象的各个部件指定的接口或抽象类

3:具体建造者(concreateBuilder) 实现接口,构建和装配各个配件

4:指挥者(director) , 构建一个使用 builder接口的对象,它主要创建一个复杂对象, 隔离了客户与产品的制造过程, 负责控制产品的制造流程

uml类图如下:

该图中,产品product 是组合到 builder抽象类中的,这样builder的实现类,都可以拿到product,从而对其属性,方法进行各自的实现, builder 和 director(指挥者)的关系是聚合, 同时,director类中,会有一个总的build方法,作为对外提供的接口, client端使用的时候,只需要使用 director类的 builder 方法,就可建造不同类型的产品了.


建造者模式在 JDK 中的应用, 比如:StringBuilder

建造者模式和 抽象工厂模式对比, 建造者模式是隔离了客户和 产品建造过程, 而抽象工厂模式,没有隔离,在client中调用时候,需要具体实现者一步一步建造产品, 这样如果再有一个房子的产品,地基500cm,墙600cm,没有顶, 相对于建造者模式来说,修改很容易, 而抽象工厂模式来说,相当于又把建造流程写了一遍,不利于维护和扩展 uml对比如下

四: 适配器模式: 目的是兼容, 将某个类的接口转换成客户期望的另一个接口表示,让原本因为接口不匹配而不能一起工作的二个类可以协同工作, 从客户的角度看不到适配过程,感觉只是和目标类接口交互,uml类图如下, 类之间的关系 Voltage5V这个是适配器接口,Voltage220V是被适配类, VoltageAdapter是适配器实现类, 实现适配器接口,并继承被适配类,

类适配器UML类图

之前说过继承不好,可以用聚合来代替, 对象适配器UML类图如下:

类适配器模式, 对象适配器模式, 都是适配器接口, 而 接口适配器模式, 是将适配器接口做成抽象类, 被适配类(220V)做成接口, 抽象类实现该接口, 这样client使用的时候,直接使用抽象类,并重写方法就可以了,很简单很灵活, 接口适配器模式UML类图如下:

适配器模式在SpringMVC 中的应用: 相信这个图我们都很熟悉了,



client发送请求到 DispatchServlet, ,,,,请求执行Hander, 这个请求就是发给了处理器适配器,HandlerAdapter, 因为处理器的类型很多,spring定义这个接口,使得每一种Controller都有对应的适配器实现类, 适配器代替controller执行相应的方法, controller和 适配器的类图如下:

五:桥接模式: 就是将 抽象化(Abstraction) 和实现化(inplermentation) 分开,使二者可以独立变化, UMl类图如下:

,

一个很常见的场景是:发送提示消息, 消息类型有 普通消息, 加急消息,特急消息, 消息发送手段又分为: 系统内短消息, 手机短消息, email

使用桥接模式就是,将消息类型 和 消息发送手段分开, 让他们独立变化, 看下图

实现类接口 和抽象类的关系是聚合, client调用的时候,创建了抽象类实例化对象,设置已经聚合对象 这样会很灵活, 消息类型和 发送手段结合,,,既能满足需求, 也避免了类爆炸,

再比如: 手机方式: 折叠,直板,侧滑, 手机品牌:小米,vivol,华为

使用桥接模式的UML类图为:


桥接模式在 JDBC源码中的使用

1:JDBC驱动程序, 2:消息管理, 3: 银行的转账系统(网上转账,柜台转账,ATM转账)(普通用户,金卡用户,vip用户)

JDBC类图如下,

六: 装饰者模式: 动态的将新功能附加到对象上, 在对象功能扩展上, 比继承更灵活,也体现了ocp原则, , 也可以理解为 实现了多种组合

很多人分不清装饰者模式 和代理模式的区别, 装饰者模式,是对同一个对象的功能加强, 代理模式是重新new了一个对象,这个新对象调用 被调用者的方法功能.

装饰者模式的UML类图如下:

可以看到, 作料的实现类中,都聚合了 饮料类, 这个饮料类属性也可以在 作料抽象类中, 作料的实现类使用的时候,直接 supper就可以了

装饰者模式在 JDK中的应用: I/O InputStream UML类图如下

七:组合模式: 又叫部分整体模式, 他创建了对象组的树形结构,将对象组成树状结构来展示 部分-整体 的层次关系

UML类图:

比如: 展示一个学校院系结构, 一个学校有多个学院,一个学院有多个系, 学校,学院,系,都继承Component,抽象类中,增删方法. 系就是叶子节点(Leaf), 学校, 学院就是(Composite)子节点, 并且在子节点类中维护有一个存储方式List , 对应的UML类图为:


组合模式在源码中的应用, 比如HashMap, 点进去后可以看到: 抽象类是Map 接口, 叶子节点是 Node(也实现了 Map接口), 子节点是 HashMap(也实现了Map接口,并在HashMap中维护了一个存储方式 node的数组:Node<K,V>[] table),对应的UML类图如下:

这里只是解析了HashMap的组合模式,平常代码过程中,也要使用组合模式, 先定义一个抽象类或接口, 抽象类中定义一些通用功能, 接着定义一个中间构件(子节点)实现抽象类/接口,重写通用功能,并在子节点中维护一个存储结构,map,list 都可以, 最后定义一个叶子节点,同样继承/实现抽象构件,里面方法可以根据特殊需要重写.

八: 外观模式: 打个比方: 电脑(包含了cpu, 硬盘,内存,屏幕)开机/关机,要依次将这四个部分开机/关机, 而实际上,我们只是点了开机按钮, 是由于电脑已经帮我们处理好了, 这四个部分就相当于 子系统角色, 开机按钮,就是电脑提供给我们的统一界面, 相当于外观角色 . 外观模式就是 定义一个高层的接口/类(外观角色), 给各个子系统一群接口(将各个子系统类,聚合到外观接口中),提供一个统一的对外访问接口, 客户直接和外观角色交互, 不和各个子系统的一群接口交互, 这样做避免了调用混乱, 对客户来说使用简单. 外观类中提供一个对外方法(方法中,各个子系统类方法依次执行),

解决了 多个子系统接口调用混乱的问题, 起到简化用户操作的目的, 比如java 的 三层开发, 也是外观模式的应用,

外观模式在源码中的应用:


九: 享元模式: 分享对象模式: 各种各样的池技术, 常量池,线程池,连接池,缓冲池等等, 比如网络围棋,棋子对象,如果都要创建的话,一盘棋要创建几百个对象, 数百人都在线,又要创建多少对象,服务器内存才够, 显然这里的棋子对象 很相似, 只是颜色和 坐标不同而已, 此时就用到了池技术(享元模式)之后,只需要二个对象即可,减小服务器内存占用, 享元模式,要区分对象的内部状态, 和外部状态, 显然,对于棋子来说,颜色是内部状态, 坐标是外部状态,

享元模式详解:

https://www.cnblogs.com/adamjwh/p/9070107.html

十: 代理模式:

静态代理: 需要代理对象,和被代理对象,都实现相同的接口或者继承相同父类, 并且,将被代理对象 聚合到代理类中, 这样代理类,能重写父类的方法,在方法中,又因为聚合了被代理对象, 所以可以针对被代理对象的方法,实现前置, 后置修改. UML类图如下:

JDK代理: 是 java 帮我们创建了目标对象的代理对象, 也是需要被代理对象有个接口, 利用Proxy.newProxyInstance(var1,var2,var3) 方法创建代理对象, var1:被代理对象的类加载器 classLoader, var2:被代理对象的接口类型, var3: InvocationHandler 事情处理,执行目标对象的方法时,会触发事情处理器方法, 会把当前执行的目标对象方法作为参数传入

cglib动态代理:不需要父类接口, 只需要被代理对象实现 MethodInterceptor接口, 重写 intercept方法, 这个方法相当于方法拦截器, 可以在方法中,调用目标方法, 前置处理, 后置处理.

相当于给被代理对象,生 了一个儿子,这个儿子就是代理对象,

https://blog.csdn.net/P19777/article/details/103998918


十一: 模板方法模式: 这个比较简单, 抽象类中,定义整个流程的多个方法(抽象方法), 这些方法推迟到子类中实现,从而实现个性化

模板方法模式在 SpringIOC容器初始化时候用到了模板方法模式, mybatis中的 BaseExcutor抽象类中用了模板方法模式, 这个抽象类实现了Excutor接口, Excutor接口中定义了一系列 操作数据库的方法:比如查询,更新,创建缓存key,删除缓存,获取事务,关闭等等方法, BaseExcutor这个抽象类中实现了一些 共性的方法比如 缓存管理,事务管理方法,有四个方法,让他的子类去重写,比如:doUpdate() 方法、doQuery() 方法、doQueryCursor() 方法、doFlushStatement() 方法, 他的UML类图如下:


十二:命令模式:

十三: 访问者模式: 这个不太明白啊

十四: 迭代器模式: 对外提供统一的集合迭代接口, 用统一的方法遍历集合元素, 不暴露内部结构

十五: 观察者模式: 又叫发布-订阅模式

十六: 中介者模式: 中介者模式: 用一个中介对象来封装一系列的对象交互, 中介者是各个对象不需要显式的相互引用, 从而使其松耦合,而且可以独立的改变他们之间的交互, 比如MVC模式.C(Controller控制器) 是M(Model模型)和V(view视图)的中介者,在前后端交互时起到了中间人作用, 中介者明细的特征是,每个同事对象都聚合了中介者, 中介者同时也聚合了每一个同事

Java设计模式:23种设计模式全面解析(超级详细)以及在源码中的应用的更多相关文章

  1. java的23种设计模式之建造者模式

    场景和本质 场景 本质 案例 原理 应用场景 场景和本质 场景 我们要建造一个复杂的产品.比如:神州飞船,Iphone.这个复杂的产品的创建.有这样一个问题需要处理:装配这些子组件是不是有个步骤问题? ...

  2. 从追MM谈Java的23种设计模式(转)

    从追MM谈Java的23种设计模式    这个是从某个文章转载过来的.但是忘了原文链接.如果知道的,我追加一下. 1.FACTORY-追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西 ...

  3. 从追MM谈Java的23种设计模式

    从追MM谈Java的23种设计模式 1.FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯 德基,只管向服务员说“来四个鸡 ...

  4. Java之——23种设计模式汇总

    在软件开发的历程中,正是无数前辈们本着追求完美的架构设计和代码设计的初心.经过无数前辈们的探索和努力,逐渐形成了一系列的设计原则和设计模式. 对于Java语言来说,通常包含有6大设计原则和23种设计模 ...

  5. JAVA:23种设计模式详解(转)

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  6. Java实现23种设计模式

    一.设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接 ...

  7. Java开发23种设计模式之禅

    六大原则 23种设计模式: 总体来说设计模式分为三大类: *创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. *结构型模式,共七种:适配器模式.装饰器模式.代理模式.外 ...

  8. Java 开发23种设计模式

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  9. Java的23种设计模式(转)

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于 ...

  10. Java的23种设计模式<一>

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代 码可靠性. 毫无疑问,设计模式 ...

随机推荐

  1. office 2007

    Microsoft office2007免费版几乎包括了Word2007.Excel2007.PowerPoint.Outlook.Publisher.OneNote.Groove.Access.In ...

  2. Windows核心编程 第四章 进程(中)

    4.2 CreateProcess函数 可以用C r e a t e P r o c e s s函数创建一个进程: BOOL CreateProcessW( _In_opt_ LPCWSTR lpAp ...

  3. C++基础:模板的声明实现分离

    模板的声明和实现为什么不能分离我不想废话了,我只是在想一种能够分离的方式. 文件 test.h 1 #pragma once 2 3 template<typename TC> 4 cla ...

  4. idea中注释变成繁体字

    原因:idea中快捷键与输入法快捷键冲突:crtl+shift+f 解决方法:修改输入法的简繁切换快捷键的设置,crtl+shift+f切换回简体输入方式 注意:如果调出全局搜索用crtl+shift ...

  5. Mybatis学习之自定义持久层框架(一) 为什么要用框架而不直接用JDBC?

    前言 说起Mybatis,相信大家都不会感到陌生,它是一款优秀的持久层框架,应用于java后端开发中,为客户端程序提供访问数据库的接口. 我们都知道,JDBC是Java语言中用来规范客户端程序如何来访 ...

  6. Nginx导航

    简介 最近都在弄微服务的东西,现在来记录下收获.我从一知半解到现在能从0搭建使用最大的感触有两点 1.微服务各大组件的版本很多,网上很多博客内容不一定适合你的版本,很多时候苦苦琢磨都是无用功 2.网上 ...

  7. Sentinel导航

    简介 最近都在弄微服务的东西,现在来记录下收获.我从一知半解到现在能从0搭建使用最大的感触有两点 1.微服务各大组件的版本很多,网上很多博客内容不一定适合你的版本,很多时候苦苦琢磨都是无用功 2.网上 ...

  8. Linux VMware Tools详解

    VMware Tools描述 VMware Tools 中包含一系列服务和模块,可在 VMware 产品中实现多种功能,从而使用户能够更好地管理客户机操作系统,以及与客户机系统进行无缝交互. 在Lin ...

  9. VMware安装RedHat7、CentOS7后无网卡解决办法

    由于Vmware虚拟网卡和linux兼容问题导致驱动无法正常安装,默认的网卡类型不兼容找到我们的Vmware虚拟机文件夹,将VMware 虚拟机配置 (.vmx),追加一条设置,网卡类型etherne ...

  10. Linux_软件包管理基本概述

    一.回去软件包的途径 1.系统发行版的光盘或官方的服务器镜像站 http://mirrors.aliyun.com        //阿里云镜像站 http://mirrors.sohu.com    ...