设计模式之单例

2019-08-05  本文已影响0人  云木杉

定义 确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

import java.util.ArrayList;
import java.util.List;

public class SingleTest {


    public static void main(String[] args) {
        Company cp = new Company() ;
        Person ceo1 = Ceo.getSiCeo() ;
        Person ceo2 = Ceo.getSiCeo() ;
        cp.addStaff(ceo1);
        cp.addStaff(ceo2);
        
        Person vp1 = new VP() ;
        Person vp2 = new VP() ;
        
        cp.addStaff(vp1);
        cp.addStaff(vp2);
        
        Person staff1 = new Staff() ;
        Person staff2 = new Staff() ;
        Person staff3 = new Staff() ;
        
        
        cp.addStaff(staff1);
        cp.addStaff(staff2);
        cp.addStaff(staff3);
        
        cp.showAllStaffs();
    }
    
}

abstract class Person{
    abstract void talk();
}


class Staff extends Person{

    @Override
    void talk() {
        // TODO Auto-generated method stub
        System.out.println("普通员工");
    }
    
}


class VP extends Person{

    @Override
    void talk() {
        // TODO Auto-generated method stub
        System.out.println("副总裁");
    }
    
}


class Ceo extends Person{

    private static final Ceo mCeo = new Ceo();
    
    public static Ceo getSiCeo() {
        return mCeo;
    }
    
    @Override
    void talk() {
        // TODO Auto-generated method stub
        System.out.println("CEO");
    }
    
}


class Company {
    private List<Person> allPersons = new ArrayList<Person>();

    public void addStaff(Person per) {
        allPersons.add(per);
    }

    public void showAllStaffs() {
        for (Person per : allPersons) {
            System.out.println("Obj : " + per.toString());
        }
    }
}


单例模式的其他实现

package com.dp.example.singleton;

public class Singleton {
    private static Singleton mInstance = null;

    private Singleton() {

    }

    public void doSomething() {
        System.out.println("do sth.");
    }

    /**
     * 方式二、double-check, 避免并发时创建了多个实例, 该方式不能完全避免并发带来的破坏.
     *  同时进来A B 线程进行实例化
     * @return
     */
    public static Singleton getInstance() {
        //1 判断 线程是否为null A进去了
        if (mInstance == null) {
            //2 A进去以后 加锁 堵塞B线程
            // 5 A释放线程 B进入
            synchronized (Singleton.class) {
                //3 判断为null A进入 实例化
                // 6 判断实例不为null 直接返回
                if (mInstance == null) {
                   //4 A实例化成功
                    mInstance = new Singleton();
                }
            }
        }
        return mInstance;
    }

    /**
     * 方式三 : 在第一次加载SingletonHolder时初始化一次mOnlyInstance对象, 保证唯一性, 也延迟了单例的实例化,
     * 如果该单例比较耗资源可以使用这种模式.
     * 
     * @return
     */
    public static Singleton getInstanceFromHolder() {
        return SingletonHolder.mOnlyInstance;
    }

    /**
     * 静态内部类
     * 
     * @author mrsimple
     *
     */
    private static class SingletonHolder {
        private static final Singleton mOnlyInstance = new Singleton();
    }

    /**
     *  方式四 : 枚举单例, 线程安全
     * @author mrsimple
     *
     */
    enum SingletonEnum {
        INSTANCE;
        public void doSomething() {
            System.out.println("do sth.");
        }
    }

    /**
     * 方式五 : 注册到容器, 根据key获取对象.一般都会有多种相同属性类型的对象会注册到一个map中
     * instance容器
     */
    private static Map<string singleton=""> objMap = new HashMap<string singleton="">();
    /**
     * 注册对象到map中
     * @param key
     * @param instance
     */
    public static void registerService(String key, Singleton instance) {
        if (!objMap.containsKey(key) ) {
            objMap.put(key, instance) ;
        }
    }
    
    /**
     * 根据key获取对象
     * @param key
     * @return
     */
    public static Singleton getService(String key) {
        return objMap.get(key) ;
    }

}

优点与缺点

优点

缺点

上一篇 下一篇

猜你喜欢

热点阅读