# DesignPattern **Repository Path**: checkergit/design-pattern ## Basic Information - **Project Name**: DesignPattern - **Description**: 设计模式的学习 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-11-04 - **Last Updated**: 2021-11-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 学习笔记-设计模式 ## 设计模式(23) ### 六大原则 **总原则——开闭原则(Open Closed Principle)OCP** > 一个软件实体,如类、模块和函数应该**对扩展开放,对修改关闭**。 在程序需要进行拓展的时候,不能去修改原有的代码,而是要扩展原有代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。 想要达到这样的效果,我们需要使用接口和抽象类等。 **1、单一职责原则(Single Responsibility Principle)** > 一个类应该只有一个发生变化的原因。 不要存在多于一个导致类变更的原因,也就是说每个类应该实现单一的职责,否则就应该把类拆分。 **2、里氏替换原则(Liskov Substitution Principle)** > 父类可以用的地方,子类也应该可以用 里氏替换原则中,**子类对父类的方法尽量不要重写和重载**。因为父类代表了定义好的结构,通过这个规范的接口与外界交互,子类不应该随便破坏它。 **3、依赖倒置原则(Dependence Inversion Principle)** > 1、上层模块不应该依赖底层模块,它们都应该依赖于抽象。 > 2、抽象不应该依赖于细节,细节应该依赖于抽象。 面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。 **4、接口隔离原则(Interface Segregation Principle)** > 1、客户端不应该依赖它不需要的接口。 > 2、类间的依赖关系应该建立在最小的接口上。 每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。 **5、迪米特法则(最少知道原则)(Law of Demeter)** > 只通过public方法进行通信; > > 只与你的直接朋友交谈,不跟“陌生人”说话。 一个类对自己依赖的类知道的越少越好。无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。 最少知道原则的另一个表达方式是:只与直接的朋友通信。类之间只要有耦合关系,就叫朋友关系。耦合分为依赖、关联、聚合、组合等。我们称出现为成员变量、方法参数、方法返回值中的类为直接朋友。局部变量、临时变量则不是直接的朋友。我们要求陌生的类不要作为局部变量出现在类中。 **6、合成复用原则(Composite Reuse Principle)** > 尽量使用对象组合/聚合,而不是继承关系达到软件复用的目的。 合成或聚合可以将已有对象纳入到新对象中,使之成为新对象的一部分,因此新对象可以调用已有对象的功能。 ### 创建型模式(5) > 提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。 #### 工厂 > 通过工厂new对象 ##### 简单工厂 > 工厂通过create方法,根据参数,将同一个产品的不同实现返回给用户 > > 一个工厂对应多个对象 ##### 工厂方法 > 工厂之上添加一个工厂接口,工厂接口返回商品总接口 > > 每个工厂都只生产一类产品 ##### 抽象工厂 > 每个商品在工厂接口中都有create方法,每个工厂都需要实现 > > 每个工厂都可以生产所有产品,用不同的方法 ##### 实例 ###### java.text.DateFormat > 简单工厂模式的运用 ```java private static DateFormat get(LocaleProviderAdapter adapter, int timeStyle, int dateStyle, Locale loc) { DateFormatProvider provider = adapter.getDateFormatProvider(); DateFormat dateFormat; if (timeStyle == -1) { dateFormat = provider.getDateInstance(dateStyle, loc); } else { if (dateStyle == -1) { dateFormat = provider.getTimeInstance(timeStyle, loc); } else { dateFormat = provider.getDateTimeInstance(dateStyle, timeStyle, loc); } } return dateFormat; } ``` ###### java.util.Collection > 工厂模式的运用 ```java public interface Collection extends Iterable { // ... Iterator iterator(); // ... } ``` ```java public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable { // ... public Iterator iterator() { return new Itr(); } private class Itr implements Iterator {...} // ... } ``` ```java public class LinkedList extends AbstractSequentialList implements List, Deque, Cloneable, java.io.Serializable { // ... public ListIterator listIterator(int index) { checkPositionIndex(index); return new ListItr(index); } private class ListItr implements ListIterator {...} //... } public interface ListIterator extends Iterator {...} ``` ###### java.util.Calendar > 简单工厂模式 ```java public abstract class Calendar implements Serializable, Cloneable, Comparable { //... private static Calendar createCalendar(TimeZone zone, Locale aLocale) { // ... Calendar cal = null; if (aLocale.hasExtensions()) { String caltype = aLocale.getUnicodeLocaleType("ca"); if (caltype != null) { switch (caltype) { case "buddhist": cal = new BuddhistCalendar(zone, aLocale); break; case "japanese": cal = new JapaneseImperialCalendar(zone, aLocale); break; case "gregory": cal = new GregorianCalendar(zone, aLocale); break; } } } // .... } // ... } ``` #### 单例 > 都需要将构造器私有化 ##### 饿汉式 > 线程安全,可能造成内存浪费,如果保证对象必然使用则可以使用 直接使用private static (final)的对象,通过getInstance()方法提供; ##### DCL > 延迟加载,线程安全 ##### 静态内部类 > 延迟加载,线程安全,利用jvm(实质内部放一个饿汉式) 通过一个静态内部类实现; ##### 枚举 > 实现最简单,通过枚举可以直接实现,避免多线程同步和反序列化,Effective Java推荐 ##### 实例 ###### Java.lang.Runtime >典型的饿汉式 ```java public class Runtime { private static Runtime currentRuntime = new Runtime(); /** * ... */ public static Runtime getRuntime() { return currentRuntime; } /** Don't let anyone else instantiate this class */ private Runtime() {} // .... } ``` ###### java.awt.Toolkit > 懒汉式单例,sychronized修饰方法保证线程安全,对象未创建的时候才进行创建 > > 这是一个AWT工具箱。它提供对本地GUI最低层次的JAVA访问。由于GUI功能不必要,所以采用懒加载 ```java public static synchronized Toolkit getDefaultToolkit() { if (toolkit == null) { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Void run() { Class cls = null; String nm = System.getProperty("awt.toolkit"); try { cls = Class.forName(nm); } catch (ClassNotFoundException e) { ClassLoader cl = ClassLoader.getSystemClassLoader(); if (cl != null) { try { cls = cl.loadClass(nm); } catch (final ClassNotFoundException ignored) { throw new AWTError("Toolkit not found: " + nm); } } } try { if (cls != null) { toolkit = (Toolkit)cls.newInstance(); if (GraphicsEnvironment.isHeadless()) { toolkit = new HeadlessToolkit(toolkit); } } } catch (final InstantiationException ignored) { throw new AWTError("Could not instantiate Toolkit: " + nm); } catch (final IllegalAccessException ignored) { throw new AWTError("Could not access Toolkit: " + nm); } return null; } }); loadAssistiveTechnologies(); } return toolkit; } ``` ###### Spring-单例Bean、单例模式、单例池 > Spring中的单例跟单例模式没太大关系,使用的ConcurrentHashMap作为单例池保存对象,方便下次获取 #### 原型 > Object clone() 方法 > > 提前创建好对象,使用时拷贝作为新建; ##### Spring-bean创建 #### 建造者 > 使用多个简单对象构建为一个复杂对象 ##### StringBuilder ### 结构型模式(7) #### 代理 > AOP > > 用一个**类**代表另一个**类**的功能,并控制对象 > > 代理转换类,适配器转换接口 > > 代理是控制,装饰器是扩展 ##### Cgllib #### 适配器 > 将**接口**转为另一个**接口** ##### Spring MVC-HandlerAdapter #### 享元 ##### Integer #### 桥接 > 让实现类和接口解耦 ##### JDBC-Driver #### 组合 > 创建对象组的树形结构 ##### HashMap #### 装饰器 > 用一个装饰类对对象添加功能 ##### FilterInputStream #### 外观 > 用一个单一的类对外,该类调度子系统 ##### Mybatis-Configuration ### 行为型模式(11) #### 责任链 ##### HandlerExecutionChain #### 状态 #### 观察者 ##### Observable #### 模板方法 ##### Spring-IOC #### 命令 ##### Spring-JdbcTemplate #### 备忘录 #### 解释器 ##### Spring-SpelExpressionParser #### 迭代器 ##### ArrayList #### 中介者 #### 策略 ##### Arrays #### 访问者