学习设计模式以前最好先了解一下设计模式的设计原则:java
1. 开闭原则(open close principle)git
开放即指对扩展开放,对修改关闭 简而言之,就是扩展功能的时候应该尽可能的不修改原有的代码。github
2. 里氏代换原则(liskov substitution principle)编程
能够简单理解为派生类与基类的替换关系,一旦程序中出现基类,那么这个基类如果呗派生类替换了,也应该是合适的,而且对程序功能不受影响,该原则其实是开闭原则的补充。 基类能真正复用,派生类也可以在基类的基础上增长新的行为。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,因此里氏代换原则是对实现抽象化的具体步骤的规范。设计模式
3. 依赖倒转原则(dependence inverse principle)缓存
这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。安全
4. 接口隔离原则(Interface Segregation Principle)多线程
使用多个隔离的接口,比使用单个接口要好,该模式出发点在与大一点的软件设计架构,便于维护升级,下降耦合度。架构
5.迪米特法则,又称最少知道原则(Demeter Principle)性能
一个实体应当尽可能少地与其余实体之间发生相互做用,使得系统功能模块相对独立。
6. 合成复用原则(Composite Reuse Principle)
尽可能使用合成/聚合的方式,而不是使用继承。
隐藏建立对象的建立逻辑,提供建立对象的接口,而非使用new关键字进行建立。
隐藏建立的对象的逻辑,经过共同对的接口建立对象。
实现demo结构以下图,实现demo代码点这里这是我学习的时候写的demo
这个模式是工厂的共工厂 叫超级工厂模式还比较贴切,在抽象工厂模式中,接口是负责建立一个相关对象的工厂,不须要显式指定它们的类。每一个生成的工厂都能按照工厂模式提供对象。
一个类负责建立本身的对象,同时确保只有单个对象被建立。这个类提供了一种访问其惟一的对象的方式,能够直接访问,不须要实例化该类的对象
public class Singleton_unsupport_multithread { private Singleton_unsupport_multithread() { // TODO Auto-generated constructor stub **} private static Singleton_unsupport_multithread instance; public static Singleton_unsupport_multithread getSingleton() { if (instance == null) { instance = new Singleton_unsupport_multithread(); } return instance; } public void println() { System.out.println("In unsupport_multithread"); } }
public class Singleton_support_multithread { private Singleton_support_multithread() { // TODO Auto-generated constructor stub } private static volatile Singleton_support_multithread instance; /** * 第一个判断能够减小锁住对象的状况 若是不为空直接返回 效率更高 * 第二个判断就是懒加载的判断 * * @return */ public static Singleton_support_multithread getInstance() { if (instance == null) { synchronized (Singleton_support_multithread.class) { if (instance == null) instance = new Singleton_support_multithread(); } } return instance; } }
/** * * @author Vincent * 线程安全 可是容易产生垃圾对象,没有加锁执行效率会比较高 * 但不是懒加载 类一加载的时候就进行初始化 浪费内存 * */ public class Singleton_hungry_man { private Singleton_hungry_man() { // TODO Auto-generated constructor stub } private static Singleton_hungry_man instance = new Singleton_hungry_man(); public static Singleton_hungry_man getInstance() { return instance; } }
/** * * @author Vincent * 登记注册式 单例 * 这里其实与前面的饿汉单例模式有点相似 可是因为利用了ClassLoaderDe特性 * 使在不调用的getInstance的时候不会初始化instance 实现了懒加载 * */ public class Singleton_register { private static class SingletonHolder { private static Singleton_register instance = new Singleton_register(); } private Singleton_register() { // TODO Auto-generated constructor stub } public static final Singleton_register getInstance() { return SingletonHolder.instance; } }
/** * * @author Vincent * 讲道理哦 这个方式最方便的单例模式 * 利用枚举 自带支持 序列化机制 防止反序列化屡次建立对象 能够适应多线程 然而却不怎么受待见 大多数人不用这个方式 可能和习惯有关系吧 = = * */ public enum Singleton_enum { Instance; }
使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于建立型模式,它提供了一种建立对象的最佳方式。值得一说的是感受是这个设计模式 感受更加注重内部对象的细节,内部零件装配的顺序。
用于建立重复的对象,同时又能保证性能
这种模式是实现了一个原型接口,该接口用于建立当前对象的克隆。当直接建立对象的代价比较大时,则采用这种模式。
这个模式感受一通常和工厂模式一块儿使用的比较多 比较方便
这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象得到新功能的方式。
将一个类的接口转换成客户但愿的另一个接口。适配器模式使得本来因为接口不兼容而不能一块儿工做的那些类能够一块儿工做。
是用于把抽象化与实现化解耦,使得两者能够独立变化,目的就是为了抽象与实现分离,均可以有独立的变化,用抽象类依赖实现类来实现。
这里简单说一下桥接模式与适配器模式的区别:从名字来理解比较容易理解,适配器嘛 那就是已经有了一些功能类,可是须要一个新的功能,这个时候不必写重复的或者说如今有可重用的功能,就须要适配器了,打个比方,你如今有一个type-c接口的手机,还有一个圆孔耳机,手机是能够不必再“钻”一个圆孔耳机孔,而耳机也不能锤扁为type-c,这个时候type-c转接头就来了,这就是一个适配器;可是桥接模式中,有一个根本的区别就是桥接模式一开始设计就是这样的架构,是为了可扩展,而不是设配器模式是为了解决问题而诞生的,这是一种设计最初就存在的模式,桥接模式通常是一个抽象实体类,而后内部拥有功能接口的引用,这种结构很方便功能实现类的扩展,还有实体类的扩展。
这个模式容许开发人员使用不一样的标准过滤一组对象,经过该逻辑运算易解耦合的方式把他们链接起来,经过结合多个标准来得到一个标准。
把一组类似的对象看成一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及总体层次,建立了对象组的树形结构,建立了一个包含本身对象组的类,该类提供修改对象组的方式。
容许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是做为现有的类的一个包装。
这种模式建立了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
该模式会隐藏系统复杂性,向现有的系统添加了一个接口。好比 电脑来说,开启电脑的是会同时开启CPU,硬盘,内存,可是咱们只管开启电脑而不须要知道其中内部的实现。
为了减小建立对象的数量来减小内存的占用提升性能,是对现有的对象尝试重用,若是没找到匹配的对象,则建立新的对象。好比:在String类中,会把建立多的字符串放在字符串缓存池里边。
注意:
1.要区别出对象的内部状态与外部状态,不然容易有引发一些线程问题 1.通常与工厂模式混合使用,便于对象的管理
在代理模式中,咱们建立具备现有对象的对象,以便向外界提供功能接口,为其余对象提供一个代理以控制对这个对象的访问。主要是为了隐藏被代理类的内部实现。
这些设计模式特别关注对象之间的通讯
请求建立了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦在这种模式中,一般每一个接收者都包含对另外一个接收者的引用。若是一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
一种数据驱动的设计模式,请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找能够处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令
提供了余元的语法或表达式的方式,属于行为模式,这种模式实现了一个表达式接口,该接口解释一个特定的上下文,通常用于SQL解析,符号处理解析引擎之类。这个模式通常比较少见。
这个模式用于顺序访问集合对象的元素,而不须要知道底层对象的表示。
用于下降多个对象和类之间的通讯复杂性。提供了中介类,这个中介类负责处理不一样类之间的通讯,使系统降耦合。
适用场景:系统对象之间存在比较复杂的引用关系,致使他们之间的依赖关系结构混乱难以复用;或者想经过一个中间类封装多个类中的行为,而又不想生成太多的子类。
当对象存在一对多的关系时候,好比:一个对象被修改的时候,就会通知他它的依赖对象。<br/>
实现方式:在抽象类里使用观察者列表。
注意事项: 使用的时候不要循环引用
类的行为是根据其状态而定的,在状态模式中,一般建立的表示状态的对象和一个行为随着状态对象改变而改变的context对象。
容许对象在内部状态发生改变的时候改变它的行为。
一个可能空对象取代null对象的例的检查,null对象不是检查空值,而是反应一个不作任何动做的关系,这样的null对象也能够在数据不可用的时候提供默认的行为。
空对象模式中,一般建立一个指定各类要执行的操做的抽象类和扩展该类的实体类,而后建立未对该类作任何实现的空对象类,该类能够无缝的使用在须要检查空值的地方。
这些设计模式特别关注表示层。这些模式是由 Sun Java Center 鉴定的。