zoukankan      html  css  js  c++  java
  • spring中用到的设计模式

    http://www.cnblogs.com/pengmengnan/p/6717766.html

    一 : 工厂模式
    工厂模式主要是为创建对象提供过度接口,以便将创建对象的具体 
    过程屏蔽隔离起来,达到提高灵活性的目的.
    工厂模式可以分为三类 : 
    (1)简单工厂模式(simple factory)
    (2)工厂方法模式 (factory method)
    (3)抽象工厂模式(abstract factory)
    ( 一 ): 简单工厂模式
    又称为静态工厂方法模式用来生产统一登记结构中任意产品,通过 
    建立一个工厂(一个函数或一个类方法)来制造新的对象.
    模式组成结构 : 
    抽象产品:他一般视具体产品继承的父类或实现的接口.在java代 
    码中由接口或者抽象类来实现.
    具体产品: 工厂类所创建的对象就是此角色的实例.在java中有一 
    个具体类来实现.
    工厂类 : 这是本模式的核心,含有一定的商业逻辑和判断逻辑.在 
    java中它往往由一个具体类实现.
    示例代码:
    抽象产品:
    public interface Car{
    void run();
    }
    具体产品 : 
    public class Audi implements Car {
    public void run(){
    System.out.println("奥迪车");
    }
    }
    public class BenChi implements Car{
    public void run(){
    System.out.println("奔驰");
    }
    }
    工厂类 :
    public class SimpleFactory{
    public Car createrCar(String type){
    if("奥迪".equals(type)){
    return new Audi();
    }else if("奔驰".equals(type)){
    return new BenChi ();
    }else {
    return null;
    }
    }
    }
    客户类(测试类) :
    public class Customer {
    public static void main(String [] args ) {
    SimpleFactory factory = new SimpleFactory ();
    Car car1 = factory .createrCar("奥迪");
    Ca r car2 = factory .createrCar("奔驰");
    }
    }

    这边是简单的工厂模式,但是工厂部分不太理想,因为每增加一种新 
    车型,都要在工厂中增加相应的创建业务逻辑,这显然是违背开闭原 
    则的.可想而知对于新的产品的加入,工厂类很是被动.
    于是工厂方法模式出现了,工厂类定义成了接口,而每新增的车型种 
    类,就增加该车种类对应的工厂类的实现,这样工厂的设计就可以拓 
    展了,而不必去修改源代码.
    (二) : 工厂方法模式
    工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模 
    式里不在只由一个工厂类决定哪一个产品被实例化,这个决定交给 
    抽象工厂的子类去做.
    模式组成结构 : 
    抽象产品: 他一般视具体产品集成的父类或者实现的接口.在java 
    中有接口或者抽象类来实现.
    具体产品 : 工厂类所创建的对象就是此角色的实例..在java中有 
    一个具体类实现.
    抽象工厂 : 这是工厂方法模式的核心,它与应用程序无关.是具体 
    工厂角色实现的接口或者必须继承的父类.在java由接口或者抽象 
    类来实现.
    具体工厂 : 它含有和具体业务逻辑有关的代码.有应用程序调用 
    以创建对应的具体产品的对象.
    示例代码 : 
    抽象产品:
    public interface Car{
    void run();
    }
    具体产品 : 
    public class Audi implements Car {
    public void run(){
    System.out.println("奥迪车");
    }
    }
    public class BenChi implements Car{
    public void run(){
    System.out.println("奔驰");
    }
    }

    抽象工厂 : 
    public interface CarFactory{
    Car createCar();
    }

    具体工厂:
    public class AuiFactory implements CarFactory{
    publuic Car createCar(){
    return new Audi();
    }
    }
    public class BenChiFactory implements CarFactory{
    publuic Car createCar(){
    return new BenChi();
    }
    }
    客户类:
    public class Customer {
    public static void main(String [] args ) {
    Car car1 = new AuiFactory .createCar();
    Car car2 = new .BenChiFactory .createCar();
    }
    }
    简单工厂模式VS工厂方法模式
    (1)结构复杂度:简单工厂模式更简单
    (2)代码复杂度 : 简单工厂模式更少
    (3)管理难度: 工厂方法模式的核心是一个抽象工厂类,而不是简单 
    工厂模式,把核心放在一个类上拓展性更好,易于管理
    根据设计理念建议使用工厂方法模式,但是实际上,我们一般使用简 
    单工厂模式.
    (三)抽象工厂模式:
    抽象工厂模式提供一个创建一系列相关或相依赖对象的接口,而无 
    需指定他们的具体的类.他针对的是有多个产品的等级结构.

    反射机制

    根据上面的工厂模式可以看出,根据需求要写出不同的对象实例化 
    的方法,因此,spring引用了反射的思想:
    根据类名可以找到其对应的类然后实例化对象,返回一个Object的 
    类.
    示例代码 : 
    工厂类 :
    public static Object getBean(String n){
    if(n!=null&&!"".equals(n)){
    try {
    return 
    Class.forName(n).newInstance(); // 通过类名 反射 实例化 
    对象
    } catch 
    (InstantiationException e) {

    e.printStackTrace();
    } catch 
    (IllegalAccessException e) {

    e.printStackTrace();
    } catch 
    (ClassNotFoundException e) {

    e.printStackTrace();
    }
    }
    return null;

    }

    客户类:
    IdCard u = (IdCard)Factory.getBean 
    ("com.jk.pojo.IdCard");
    因为返回的是一个Object所以要强转
    二 : 单例模式
    一 : 饿汉模式 
    特点:
    在类装载的时候就初始化Singleton,有时候不是调用getInstance 
    方法,调用别的静态方法,也会让类进行静态加载,但是,此时并不一 
    定想实例化Singleton,造成资源的浪费.
    这种方式基于classloder机制避免了多线程的同步问题,不过, 
    instance在类装载时就实例化,虽然导致类装载的原因有很多种, 
    在单例模式中大多数都是调用getInstance方法, 但是也不能确 
    定有其他的方式(或者其他的静态方法)导致类装载,这时候初始 
    化instance显然没有达到lazy loading的效果。
    代码示例:
    1. public class Singleton { 
    2. private static Singleton instance = new 
    Singleton(); 
    3. private Singleton (){} //私有化有参构造
    4. public static Singleton getInstance() { 
    5. return instance; 
    6. } 
    7. }


    二:饿汉模式变种
    表面上看起来差别挺大,其实更第三种方式差不多,都是在类初始 
    化即实例化instance。只是将实例化的对象放到了静态代码块中
    示例代码:
    1. public class Singleton { 
    2. private Singleto+n instance = null; 
    3. static { 
    4. instance = new Singleton(); 
    5. } 
    6. private Singleton (){} 
    7. public static Singleton getInstance() { 
    8. return this.instance;
    9. } 
    10. } 
    三 : 懒汉模式(线程安全的)
    (1)
    特点 : 没有加ysnchronized的懒汉模式,是线程不安全的,比如说 
    一个线程来了判断instance是null,就去实例化Singleton了,在实 
    例化之前,这是另一个线程来判断这个instance,发现也是null所 
    以又去实例化一次,所以严格上来说不加synchronized懒汉模式, 
    不是单例模式.synchronized 是让访问的客户自动去排队因此即 
    使前面已经判断过不为空了,但后面的访问还是要一个一个的去排 
    队访问,所以效率低
    示例代码:
    1. public class Singleton { 
    2. private static Singleton instance; 
    3. private Singleton (){} 
    4. public static synchronized Singleton 
    getInstance() { 
    5. if (instance == null) { 
    6. instance = new Singleton(); 
    7. } 
    8. return instance; 
    9. } 
    10. } 
    (2)双重校验锁(重点)
    加了双重校验锁的懒汉模式既可以使线程安全又不会影响效率,因 
    为,第一次排队实例化第一个对象之后,下面在有访问的就直接被第 
    一个if拦截住了,所以不需要去排队访问
    示例代码
    public class Singleton {
    private Singleton(){};//私有化构造器
    private static volatile Singleton instance = null; 
    // volatile 不稳定
    public static Singleton getInstance(){ // 
    synchronized 同步锁 线程锁
    if(instance==null){ // 双重判定锁 
    synchronized (Singleton.class){
    if(instance ==null){
    instance = new Singleton ();
    }
    }
    }
    return instance ;
    }
    }
    四 : 懒汉式(线程不安全)
    这种写法lazy loading很明显,但是致命的是在多线程不能正常 
    工作。比如说一个线程来了判断instance是null,就去实例化 
    Singleton了,在实例化之前,这是另一个线程来判断这个 
    instance,发现也是null所以又去实例化一次,所以严格上来说不 
    加synchronized懒汉模式,不是单例模式.
    1. public class Singleton { 
    2. private static Singleton instance; 
    3. private Singleton (){} 
    4. 
    5. public static Singleton getInstance() { 
    6. if (instance == null) { 
    7. instance = new Singleton(); 
    8. } 
    9. return instance; 
    10. } 
    11. }
    五 : (静态内部类)
    1. public class Singleton { 
    2. private static class SingletonHolder { 
    3. private static final Singleton INSTANCE = new 
    Singleton(); 
    4. } 
    5. private Singleton (){} 
    6. public static final Singleton getInstance() { 

    7. return SingletonHolder.INSTANCE; 
    8. } 
    9. } 
    这种方式同样利用了classloder的机制来保证初始化 
    instance时只有一个线程,它跟第三种和第四种方式不同的是(很 
    细微的差别):第三种和第四种方式是只要Singleton类被装载了 
    ,那么instance就会被实例化(没有达到lazy loading效果), 
    而这种方式是Singleton类被装载了,instance不一定被初始化。 
    因为SingletonHolder类没有被主动使用,只有显示通过调用 
    getInstance方法时,才会显示装载SingletonHolder类,从而实 
    例化instance。想象一下,如果实例化instance很消耗资源,我 
    想让他延迟加载,另外一方面,我不希望在Singleton类加载时就 
    实例化,因为我不能确保Singleton类还可能在其他的地方被主动 
    使用从而被加载,那么这个时候实例化instance显然是不合适的。 
    这个时候,这种方式相比第三和第四种方式就显得很合理
    六 : 枚举
    1. public enum Singleton { 
    2. INSTANCE; 
    3. public void whateverMethod() { 
    4. } 
    5. } 
    这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅 
    能避免多线程同步问题,而且还能防止反序列化重新创建新的对象 
    ,可谓是很坚强的壁垒啊,不过,个人认为由于1.5中才加入enum 
    特性,用这种方式写不免让人感觉生疏,在实际工作中,我也很少 
    看见有人这么写过

  • 相关阅读:
    Node 之http模块
    Node 之 模块加载原理与加载方式
    Node 之NPM介绍
    Node.js的特点
    ECMAScript 6 简介
    Node 之URL模块
    用户模块 之 根据条件查询用户
    用户模块 之 完成用户列表的分页显示
    用户模块 之 完成查询所有帖子、完成查询所有回复以及点赞
    用户模块 之 完成查询所有用户
  • 原文地址:https://www.cnblogs.com/xiaohouzai/p/7350987.html
Copyright © 2011-2022 走看看