设计模式

  • 设计模式
  • 1单例模式
  • 2工厂模式

设计模式

  • 创建型模式:对类的实例化过程的抽象化【Factory
    Method(工厂方法模式)、AbstractFactory(抽象工厂模式)、Singleton(单例模式)、Builder(建造者模式)、Prototype(原始模型模式)】
  • 结构型模式:描述如何将类或对象结合在一起形成更大的结构【Adapter(适配器模式)、Decorator(装饰模式)、Proxy(代理模式)、Facade(门面模式、Bridge(桥梁模式)、Composite(合成模式)、Flyweight(享元模式)】
  • 行为型模式:对在不同的对象之间划分责任和算法的抽象化【Strategy(策略模式)、Template Method(模板方法模式)、Observer(观察者模式)、Iterator(迭代子模式)、Chain Of Responsibility(责任链模式)、Command(命令模式)、Memento(备忘录模式)、State(状态模式)、Visitor(访问者模式)、Mediator(调停者模式、Interpreter(解释器模式)】
  • 还有两类:并发型模式和线程池模式。

1单例模式

  • 系统中只会同时存在最多一个实例对象

1.饿汉式单例模式

package com.anran.design.patterns;

/**
 * @author anran
 * @version 创建时间:2017年9月10日 上午9:23:36 类说明 : 饿汉式单例模式(系统中只会同时存在最多一个实例对象)
 */
public class Singleton {

    // 在初次创建对象或者调用本类中静态方法的时候会被初始化
    private static final Singleton signleton = new Singleton();

    // 单例模式需要构造器私有化
    private Singleton() {
        // TODO Auto-generated constructor stub
    }

    // 通过静态方法获取系统中唯一的对象(线程安全的)
    public static Singleton getInstance() {
        return signleton;
    }

}

2.懒汉式单例模式

package com.anran.design.patterns;

/**
 * @author anran
 * @version 创建时间:2017年9月10日 上午9:29:47 类说明 : 懒汉式单例模式(系统中只会同时存在最多一个实例对象)
 */
public class Singleton2 {

    // 第一次进入的时候对象是null,需要赋值操作
    private volatile static Singleton2 signleton2 = null;

    // 单例模式需要构造器私有话
    private Singleton2() {
        // TODO Auto-generated constructor stub
    }

    // 存在线程安全,假如两个线程同时走到if判断,那么就会出现创建出多个实例的情况
    public static Singleton2 getInstance() {
        if (null == signleton2) {
            signleton2 = new Singleton2();
        }
        return signleton2;
    }

    // 线程安全(将方法进行线程同步),但是存在性能问题(比如该方法中有很多耗时的操作)
    public synchronized static Singleton2 getInstance1() {
        // do somthing
        if (null == signleton2) {
            signleton2 = new Singleton2();
        }
        return signleton2;
    }

    // 线程安全??(将代码块线程同步)
    // 线程安全还存在一定的风险,因为创建对象的底层操作大致分为1:分配对象的内存空间,2:在内存初始化对象信息,3:设置引用指向内存空间
    // 其中2、3有可能因为底层的重排序,导致顺序调换。
    // 假如线程一执行完3,但是没有执行2,此时线程二正好运行到第一个if中获得的结果是引用不为空,此时就会导致线程二获得一个没有初始化完成的对象。
    // 为了防止上面问题的出现,可以将单例对象声明为volatile (禁止编译器的优化,按照顺序执行),因此这样就能使得线程安全
    public static Singleton2 getInstance2() {
        // do somthing
        if (null == signleton2) {
            // 等待锁
            synchronized (Singleton.class) {
                // 获取到对象锁,还需要再次判断,防止在等锁期间有人实例化
                if (null == signleton2) {
                    signleton2 = new Singleton2();
                }
            }
        }
        return signleton2;
    }

    // 通过静态内部类实现线程安全
    private static class LazyHolderss {
        // 初始化
        private static final Singleton2 INSTANCE = new Singleton2();
    }

    public static Singleton2 getInstance3() {
        return LazyHolderss.INSTANCE;
    }

}

3.登记式单例模式

package com.anran.design.patterns;

import java.util.HashMap;
import java.util.Map;

/**
 * @author anran
 * @version 创建时间:2017年9月10日 上午10:11:23 类说明 : 登记式单例模式(系统中只会同时存在最多一个实例对象)
 */
public class Singleton3 {

    // 单例模式需要构造器私有化(为了子类可以继承该父类,map中方的是该父类型的数据)
    protected Singleton3() {
    }

    private static Map map = new HashMap();
    static {
        Singleton3 single = new Singleton3();
        map.put(single.getClass().getName(), single);
    }

    public static Singleton3 getInstance(String name) {
        if (name == null) {
            name = Singleton3.class.getName();
            System.out.println("name == null" + "--->name=" + name);
        }
        if (map.get(name) == null) {
            try {
                map.put(name, (Singleton3) Class.forName(name).newInstance());
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        return map.get(name);
    }

    // 一个示意性的商业方法
    public String about() {
        return "Hello, I am RegSingleton.";
    }
}

2工厂模式

为什么使用工厂模式?

  • 为了完成两个模块之间的解耦,用工厂模式,你只需要修改工厂代码。其他地方引用工厂,可以做到只修改一个地方,其他代码都不动。

工厂模式分类:

  • 简单工厂模式(Simple Factory)
  • 工厂方法模式(Factory Method)
  • 抽象工厂模式(Abstract Factory)

    这三种模式从上到下逐步抽象,并且更具一般性。

例如:

  • 还没有工厂时代:假如还没有工业革命,如果一个客户要一款宝马车,一般的做法是客户去创建一款宝马车,然后拿来用。
  • 简单工厂模式:后来出现工业革命。用户不用去创建宝马车。因为客户有一个工厂来帮他创建宝马.想要什么车,这个工厂就可以建。比如想要320i系列车。工厂就创建这个系列的车。即工厂可以创建产品。
  • 工厂方法模式时代:为了满足客户,宝马车系列越来越多,如320i,523i,30li等系列一个工厂无法创建所有的宝马系列。于是由单独分出来多个具体的工厂。每个具体工厂创建一种系列。即具体工厂类只能创建一个具体产品。但是宝马工厂还是个抽象。你需要指定某个具体的工厂才能生产车出来。
  • 抽象工厂模式时代:随着客户的要求越来越高,宝马车必须配置空调。于是这个工厂开始生产宝马车和需要的空调。

    最终是客户只要对宝马的销售员说:我要523i空调车,销售员就直接给他523i空调车了。而不用自己去创建523i空调车宝马车. 这就是工厂模式。

1.不使用工厂模式的代码

//对象1
public class NoFactoryObject1 {
    public void use() {
        System.out.println("NoFactoryObject1");
    }
}
//对象2
public class NoFactoryObject2 {
    public void use() {
        System.out.println("NoFactoryObject2");
    }
}
//使用方法
public class NoFactoryUse {
    public static void main(String[] args) {
        NoFactoryObject1 noFactoryObject1 = new NoFactoryObject1();
        noFactoryObject1.use();
        NoFactoryObject2 noFactoryObject2 = new NoFactoryObject2();
        noFactoryObject2.use();
    }
}


总结:如果在出现一个新的对象,在使用者这块需要写入新的代码,并且到处都是new出来的对象,不利于后期的修改。

2.简单工厂模式

//创建对象抽象类
public interface SimpleFactoryObject {
    public void use();
}
//创建对象的具体实现1
public class SimpleFactoryObject1 implements SimpleFactoryObject {
    public void use() {
        System.out.println("SimpleFactoryObject1");
    }
}
//创建对象的具体实现2
public class SimpleFactoryObject2 implements SimpleFactoryObject {
    public void use() {
        System.out.println("SimpleFactoryObject2");
    }
}
//创建工厂类
package com.anran.design.factory;

/**
 * @author anran
 * @version 创建时间:2017年9月10日 下午12:29:58 类说明 :
 */
public class SimpleFactory {
    public SimpleFactoryObject getSimpleFactoryObject(int i) {
        SimpleFactoryObject simpleFactoryObject = null;
        switch (i) {
        case 1:
            simpleFactoryObject = new SimpleFactoryObject1();
            break;
        case 2:
            simpleFactoryObject = new SimpleFactoryObject2();
            break;
        default:
            break;
        }
        return simpleFactoryObject;
    }
}
//使用方法
public class SimpleFactoryUse {
    public static void main(String[] args) {
        SimpleFactory factory = new SimpleFactory();
        SimpleFactoryObject object = factory.getSimpleFactoryObject(1);
        object.use();
    }
}


总结:
优点:将对象创建移至工厂中,使得使用者和对象解耦,后期维护比较方便。
缺点:对象的创建符合开闭原则,但是工厂的代码就不符合,当新天添加一种参品的时候,就需要对工厂中的代码就行修改。

3.工厂方法模式

//创建对象抽象类
public interface MethodFactoryObject {
    public void use();
}
//创建对象的具体实现1
public class MethodFactoryObject1 implements MethodFactoryObject {
    public void use() {
        System.out.println("MethodFactoryObject1");
    }
}
//创建对象的具体实现2
public class MethodFactoryObject2 implements MethodFactoryObject {
    public void use() {
        System.out.println("MethodFactoryObject2");
    }
}
//创建抽象工厂类
public interface MethodFactory{
    public MethodFactoryObject createMethodFactoryObject();
}
//创建工厂类实现1
public class MethodFactory1 implements MethodFactory {
    @Override
    public MethodFactoryObject createMethodFactoryObject() {
        return new MethodFactoryObject1();
    }
}
//创建工厂类实现2
public class MethodFactory2 implements MethodFactory {
    @Override
    public MethodFactoryObject createMethodFactoryObject() {
        return new MethodFactoryObject2();
    }
}
//创建使用方法
public class MethodFactoryUse {
    public static void main(String[] args) {
        MethodFactory factory = new MethodFactory2();
        MethodFactoryObject object = factory.createMethodFactoryObject();
        object.use();
    }
}


总结:
优点;产品和工厂都符合开闭原则。
缺点:随着产品数量的不断增加,工厂数量也会不断的增加,后期维护也会出现困难。如果不能避免这种情 况,可以考虑使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类。

4.抽象工厂模式

//创建对象一抽象类
public interface AbstractFactoryObjectOne {
    public void use();
}
//创建对象一的具体实现1
public class AbstractFactoryObjectOne1 implements AbstractFactoryObjectOne {
    public void use() {
        System.out.println("AbstractFactoryObjectOne1");
    }
}
//创建对象一的具体实现2
public class AbstractFactoryObjectOne2 implements AbstractFactoryObjectOne {
    public void use() {
        System.out.println("AbstractFactoryObjectOne2");
    }
}


//创建对象二抽象类
public interface AbstractFactoryObjectTwo {
    public void use();
}
//创建对象二的具体实现1
public class AbstractFactoryObjectTwo1 implements AbstractFactoryObjectTwo {
    public void use() {
        System.out.println("AbstractFactoryObjectTwo1");
    }
}
//创建对象二的具体实现2
public class AbstractFactoryObjectTwo2 implements AbstractFactoryObjectTwo {
    public void use() {
        System.out.println("AbstractFactoryObjectTwo2");
    }
}


//创建抽象工厂类
public interface AbstractFactory{
    public AbstractFactoryObjectOne createAbstractFactoryObjectOne();
    public AbstractFactoryObjectTwo createAbstractFactoryObjectTwo();
}
//创建工厂类实现1
public class AbstractFactory1 implements AbstractFactory {
    @Override
    public AbstractFactoryObjectOne createAbstractFactoryObjectOne(){
        return new AbstractFactoryObjectOne1();
    }
    @Override
    public AbstractFactoryObjectTwo createAbstractFactoryObjectTwo(){
        return new AbstractFactoryObjectTwo1();
    }
}
//创建工厂类实现2
public class AbstractFactory2 implements AbstractFactory {
    @Override
    public AbstractFactoryObjectOne createAbstractFactoryObjectOne(){
        return new AbstractFactoryObjectOne2();
    }
    @Override
    public AbstractFactoryObjectTwo createAbstractFactoryObjectTwo(){
        return new AbstractFactoryObjectTwo2();
    }
}



//创建使用方法
public class MethodFactoryUse {
    public static void main(String[] args) {
        AbstractFactory factory = new AbstractFactory2();
        AbstractFactoryObjectOne objectOne = factory.createAbstractFactoryObjectOne();
        objectOne.use();
        AbstractFactoryObjectTwo objectTwo = factory.createAbstractFactoryObjectTwo();
        objectTwo.use();
    }
}


总结:抽象工厂模式就是将多个不同的产品放在同一个工厂中创建,从而满足用户的使用。(当产品只有一个的时候相当于工厂方法模式)

你可能感兴趣的:(设计模式)