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

    一 : 工厂模式
    工厂模式主要是为创建对象提供过度接口,以便将创建对象的具体
    过程屏蔽隔离起来,达到提高灵活性的目的.
    工厂模式可以分为三类 :
    (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
    特性,用这种方式写不免让人感觉生疏,在实际工作中,我也很少
    看见有人这么写过

  • 相关阅读:
    131. 分割回文串
    博客开通第二十七天
    博客开通第三十八天
    博客开通第56天
    博客开通第三十三天
    博客开通第61天
    博客开通第62天
    博客开通第二十六天
    博客开通第四十七天
    博客开通第63天
  • 原文地址:https://www.cnblogs.com/pengmengnan/p/6717766.html
Copyright © 2011-2022 走看看