JAVA设计模式

#1、面向对象OOP 面向对象设计的任务是对面向对象分析的结果做进一步的规范化整理,以便可以被面向对象编程直接接受。
面向对象设计是一种软件设计方法,是一种工程化规范。
归纳地说,面向对象设计就是“根据需求决定所需的类、类的操做,以及类之间关联的过程”。编程

面向对象设计的主要工做包括:设计模式

  • 肯定须要的类;
  • 给每一个类提供一组完整的操做;
  • 明确地使用继承来表现共同点。

主要原则:数组

  • 模块化,对象就是模块;把数据结构和操做这些数据的方法紧密地结合在一块儿所构成的模块。
  • 抽象,面向对象方法不只支持过程抽象,并且支持数据抽象。
  • 信息隐藏,在面向对象方法中,信息隐藏经过对象的封装性来实现。
  • 低耦合,耦合主要指不一样对象之间相互关联的紧密程度。低耦合使得系统中某一部分的变化对其余部分的影响降到最低程度。

#2、设计原则安全

  1. 单一职责原则 (Single Responsibility Principle, SRP) 一个类只负责一个功能领域中的相应职责;
  2. 开闭原则 (Open-Closed Principle, OCP) 软件实体应对扩展开放,而对修改关闭;
  3. 里氏代换原则 (Liskov Substitution Principle, LSP)全部引用基类对象的地方可以透明地使用其子类的对象;
  4. 依赖倒转原则 (Dependence Inversion Principle, DIP) 抽象不该该依赖于细节,细节应该依赖于 抽象;
  5. 接口隔离原则 (Interface Segregation Principle, ISP) 使用多个专门的接口,而不使用单一的总接 口 ;
  6. 合成复用原则 (Composite Reuse Principle, CRP) 尽可能使用对象组合,而不是继承来达到复用的 目的;
  7. 迪米特法则 (Law of Demeter, LoD) 一个软件实体应当尽量少地与其余实体发生相互做用。

#3、设计模式数据结构

##建立型模式 ###1. 简单工厂模式多线程

定义一个工厂类,它能够根据参数的不一样返回不一样类的实例,被建立的实例一般都具备共同的父类。由于在简单工厂模式中用于建立实例的方法是静态(static)方法,所以简单工厂模式又被称为静态工厂方法(Static Factory Method)模式。app

简单工厂模式的要点在于:当你须要什么,只须要传入一个正确的参数,就能够获取你所须要的对象,而无须知道其建立细节。简单工厂模式结构比较简单,其核心是工厂类的设计。编程语言

主要角色: Factory(工厂角色) - Product(抽象产品角色)- ConcreteProduct(具体产品角色) 输入图片说明模块化

###2. 工厂方法模式函数

定义一个用于建立对象的接口,让子类决定将哪个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式(Factory Pattern),又可称做虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern)。

工厂方法模式提供一个抽象工厂接口来声明抽象工厂方法,而由其子类来具体实现工厂方法,建立具体的产品对象。

主要角色: Factory(抽象工厂) - ConcreteFactory(具体工厂) - Product(抽象产品) - ConcreteProduct(具体产品) 输入图片说明

###3. 抽象工厂模式

提供一个建立一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式。在抽象工厂模式中,每个具体工厂都提供了多个工厂方法用于产生多种不一样类型的产品,这些产品构成了一个产品族。

主要角色:AbstractFactory(抽象工厂) - ConcreteFactory(具体工厂)- AbstractProduct(抽象产品)- ConcreteProduct(具体产品) 输入图片说明

###4. 单例模式

确保某一个类只有一个实例,并且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。

单例模式有三个要点:一是某个类只能有一个实例;二是它必须自行建立这个实例;三是它必须自行向整个系统提供这个实例。

主要角色:Singleton(单例):在单例类的内部实现只生成一个实例,同时它提供一个静态getInstance()工厂方法,让客户能够访问它的惟一实例;为了防止在外部对其实例化,将其构造函数设计为私有;在单例类内部定义了一个Singleton类型的静态对象,做为外部共享的惟一实例。

输入图片说明

  • 饿汉式
class EagerSingleton {
    private static final EagerSingleton instance = new EagerSingleton();
    private EagerSingleton() { }
    public static EagerSingleton getInstance() {
        return instance;
    }
}
  • 懒汉式
class LazySingleton {
    private volatile static LazySingleton instance = null;
    private LazySingleton() { }
    public static LazySingleton getInstance() {
        //第一重判断
        if (instance == null) {
            //锁定代码块
            synchronized (LazySingleton.class) {
                //第二重判断
                if (instance == null) {
                        instance = new LazySingleton(); //建立单例实例
                }
            }
        }
    return instance;
    }
}
  • Initialization Demand Holder (IoDH):在单例类中增长一个静态(static)内部类,在该内部类中建立单例对象,再将该单例对象经过getInstance()方法返回给外部使用。
class Singleton {
    private Singleton() {
    }
    private static class HolderClass {
        private final static Singleton instance = new Singleton();
    }
    public static Singleton getInstance() {
        return HolderClass.instance;
    }
    public static void main(String args[]) {
        Singleton s1, s2;
        s1 = Singleton.getInstance();
        s2 = Singleton.getInstance();
        System.out.println(s1==s2);
    }
}

饿汉式单例类在类被加载时就将本身实例化,它的优势在于无须考虑多线程访问问题,能够确保实例的惟一性;从调用速度和反应时间角度来说,因为单例对象一开始就得以建立,所以要优于懒汉式单例。可是不管系统在运行时是否须要使用该单例对象,因为在类加载时该对象就须要建立,所以从资源利用效率角度来,饿汉式单例不及懒汉式单例,并且在系统加载时因为须要建立饿汉式单例对象,加载时间可能会比较长。

懒汉式单例类在第一次使用时建立,无须一直占用系统资源,实现了延迟加载,可是必须处理好多个线程同时访问的问题,特别是当单例类做为资源控制器,在实例化时必然涉及资源初始化,而资源初始化颇有可能耗费大量时间,这意味着出现多线程同时首次引用此类的机率变得较大,须要经过双重检查锁定等机制进行控制,这将致使系统性能受到必定影响。

饿汉式单例类不能实现延迟加载,无论未来用不用始终占据内存;懒汉式单例类线程安全控 制烦琐,并且性能受影响。经过使用IoDH,咱们既能够实现延迟加载,又能够保证线程安全,不影响系统性能,不失为一种最好的Java语言单例模式实现方式(其缺点是与编程语言自己的特性相关,不少面向对象 语言不支持IoDH)。

###5. 原型模式

使用原型实例指定建立对象的种类,而且经过拷贝这些原型建立新的对象。

工做机制:将一个原型对象传给那个要发动建立的对象,这个要发动建立的对象经过请求原型对象拷贝本身来实现建立过程。因为在软件系统中咱们常常会遇到须要建立多个相同或者类似对象的状况,所以原型模式在真实开发中的使用频率仍是很是高的。原型模式是一种“另类”的建立型模式,建立克隆对象的工厂就是原型类自身,工厂方法由克隆方法来实现。

须要注意的是经过克隆方法所建立的对象是全新的对象,它们在内存中拥有新的地址,一般对克隆所产生的对象进行修改对原型对象不会形成任何影响,每个克隆对象都是相互独立的。经过不一样的方式修改能够获得一系列类似但不彻底相同的对象。

主要角色: Prototype(抽象原型类) - ConcretePrototype(具体原型类) - Client(客户类)

克隆方法:浅克隆(ShallowClone)和深克隆(DeepClone)。在Java语言中,数据类型分为值类型(基本数据类型)和引用类型,值类型包括int、double、byte、boolean、char等简单数据类型,引用类型包括类、接口、数组等复杂类型。浅克隆和深克隆的主要区别在因而否支持引用类型的成员变量的复制。

  • 浅克隆(ShallowClone) (implements Cloneable) 当对象被复制时只复制它自己和其中包含的值类型的成员变量,而引用类型的成员对象并无复制; 输入图片说明

  • 深克隆(DeepClone) (implements Serializable ) 除了对象自己被复制外,对象所包含的全部成员变量也将复制。
    输入图片说明

###6. 建造者模式

将一个复杂对象的构建与它的表示分离,使得一样的构建过程能够建立不一样的表示。建造者模式是一种对象建立型模式。

建造者模式一步一步建立一个复杂的对象,它容许用户只经过指定复杂对象的类型和内容就能够构建它们,用户不须要知道内部的具体构建细节。

主要角色:Builder(抽象建造者) - ConcreteBuilder(具体建造者) - Product(产品角色) - Director(指挥者)

输入图片说明

##结构型模式 ###1. 适配器模式

将一个接口转换成客户但愿的另外一个接口,使接口不兼容的那些类能够一块儿工做,其别名为包装器(Wrapper)。适配器模式既能够做为类结构型模式,也能够做为对象结构型模式。

将一个类的接口和另外一个类的接口匹配起来,而无须修改原来的适配者接口和抽象目标类接口。

  • 对象适配器
    适配器与适配者之间是关联关系
    主要角色:
    Target(目标抽象类) :目标抽象类定义客户所需接口,能够是一个抽象类或接口,也能够是具体类。
    Adapter(适配器类):适配器能够调用另外一个接口,做为一个转换器,对Adaptee和Target进行适配,适配器类是适配器模式的核心,在对象适配器中,它经过继承Target并关联一个Adaptee对象使两者产生联系。
    Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口须要适配,适配者类通常是一个具体类,包含了客户但愿使用的业务方法,在某些状况下可能没有适配者类的源代码。
    输入图片说明
  • 类适配器
    适配器与适配者之间是继承(或实现)关系
    适配器类实现了抽象目标类接口Target,并继承了适配者类,在适配器类的request()方法中调用所继承的适配者类的specificRequest()方法,实现了适配。
    输入图片说明

优势:
1)将目标类和适配者类解耦,经过引入一个适配器类来重用现有的适配者类,无须修改原有结构。
2)增长了类的透明性和复用性
3)灵活性和扩展性都很是好,经过使用配置文件,能够很方便地更换适配器,也能够在不修改原有代码的基础上增长新的适配器类,彻底符合“开闭原则”。

  • 双向适配器
  • 缺省适配器

###2. 代理模式

给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。

代理模式是一种对象结构型模式。在代理模式中引入了一个新的代理对象,代理对象在客户端对象和目标对象之间起到中介的做用,它去掉客户不能看到的内容和服务或者增添客户须要的额外的新服务。

主要角色:
1)Subject(抽象主题角色):它声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方均可以使用代理主题,客户端一般须要针对抽象主题角色进行编程。
2) Proxy(代理主题角色):它包含了对真实主题的引用,从而能够在任什么时候候操做真实主题对象;在代理主题角色中提供一个与真实主题角色相同的接口,以便在任什么时候候均可以替代真实主题;代理主题角色还能够控制对真实主题的使用,负责在须要的时候建立和删除真实主题对象,并对真实主题对象的使用加以约束。一般,在代理主题角色中,客户端在调用所引用的真实主题操做以前或以后还须要执行其余操做,而不只仅是单纯调用真实主题对象中。 3) RealSubject(真实主题角色):它定义了代理角色所表明的真实对象,在真实主题角色中实现了真实的业务操做,客户端能够经过代理主题角色间接调用真实主题角色中定义的操做。 输入图片说明
优势:
1)可以协调调用者和被调用者,在必定程度上下降了系统的耦合度; 2)客户端能够针对抽象主题角色进行编程,增长和更换代理类无须修改源代码,符合开闭原则,系统具备较好的灵活性和可扩展性。
缺点:
1)因为在客户端和真实主题之间增长了代理对象,所以有些类型的代理模式可能会形成请求的处理速度变慢,例如保护代理。
2)实现代理模式须要额外的工做,并且有些代理模式的实现过程较为复杂,例如远程代理。

###3. 桥接模式

将抽象部分与它的实现部分分离,使它们均可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。

桥接模式用一种巧妙的方式处理多层继承存在的问题,用抽象关联取代了传统的多层继承,将类之间的静态继承关系转换为动态的对象组合关系,使得系统更加灵活,并易于扩展,同时有效控制了系统中类的个数。 输入图片说明

###4. 外观模式

为子系统中的一组接口提供一个统一的入口。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

外观模式又称为门面模式,它是一种对象结构型模式。外观模式是迪米特法则的一种具体实现,经过引入一个新的外观角色能够下降原有系统的复杂度,同时下降客户类与子系统的耦合度。 输入图片说明

###5. 组合模式

组合多个对象造成树形结构以表示具备“总体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具备一致性,组合模式又能够称为“总体—部分”(Part-Whole)模式,它是一种对象结构型模式。

###6. 装饰模式

动态地给一个对象增长一些额外的职责,就增长对象功能来讲,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。

在装饰模式中,为了让系统具备更好的灵活性和可扩展性,咱们一般会定义一个抽象装饰类,而将具体的装饰类做为它的子类。

###7. 享元模式

运用共享技术有效地支持大量细粒度对象的复用。系统只使用少许的对象,而这些对象都很类似,状态变化很小,能够实现对象的屡次复用。因为享元模式要求可以共享的对象必须是细粒度对象,所以它又称为轻量级模式,它是一种对象结构型模式。

##行为型模式

  1. 观察者模式
  2. 访问者模式
  3. 中介者模式
  4. 模版方法模式
  5. 策略模式
  6. 状态模式
  7. 备忘录模式
  8. 迭代器模式
  9. 解释器模式
  10. 命令模式
  11. 职责链模式
相关文章
相关标签/搜索