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.";
}
}
为什么使用工厂模式?
工厂模式分类:
抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
例如:
抽象工厂模式时代:随着客户的要求越来越高,宝马车必须配置空调。于是这个工厂开始生产宝马车和需要的空调。
最终是客户只要对宝马的销售员说:我要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();
}
}
总结:抽象工厂模式就是将多个不同的产品放在同一个工厂中创建,从而满足用户的使用。(当产品只有一个的时候相当于工厂方法模式)