设计模式之单例模式

设计模式之单例模式


    单例模式(Single Pattern)定义:Ensurena a class has only one instance, and provide a global point of access to it.(确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例)

通用类:


    Singleton类称为单例类,通过使用private的构造函数,确保了在一个应用中只产生一个实例,并且是自行实例化的,代码:

public class Singleton {
	private static final Singleton singleton=new Singleton();
	//限制产生多少个对象
	private Singleton(){
	}
	//通过该方法获得对象实例
	public static Singleton getSingleton(){
		return singleton;
	}
	//类中其它方法,尽量是static
	public static void doSomething(){
	}
}

例子:

皇帝类

public class Emperor {
	private static final Emperor emperor=new Emperor();
	private Emperor(){
	}
	public static Emperor getInstance(){
		return emperor;
	}
	public static void say(){
		System.out.println("我是皇帝某某某......");
	}
}

臣子类

public class Minister {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		for(int day=0;day<3;++day){
			Emperor emperor=Emperor.getInstance();
			emperor.say();
		}
	}
}

单例模式优点

1.在内存中只有一个实例,减少内存开支,当一个对象需要频繁的创建销毁时,并且创建或销毁时性能又无法优化,单例模式的优势就非常明显;

2.单例模式只产生一个实例,减少了系统开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其它依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存来解决;

3.单例模式能够避免对资源的多重占用,如一个写文件动作,由于只有一个实例在内存中,比面对同一个资源文件的同时读写操作;

4.单例模式可以在系统中设置全局的访问点,优化和共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理。

单例模式的缺点

1.单例模式没有接口,扩展极其困难,若要扩展,除了修改代码基本没有第二种方法;

2.单例模式是对测试不利的;

3.单例模式与单一职责有冲突。一个类应该只实现一个逻辑,而不关心它是否是单例的,是不是要单例取决于环境,单例模式把“要单例”和业务逻辑融合在一个类中。

单例模式应用场景

1.要求生成唯一序列号的环境;

2.在整个项目中需要一个共享访问点或共享数据,例如一个Web页面上的计数器,可以不用把每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的;

3.创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源;

4.需要定义大量的静态常量和静态方法的环境。

非线程安全的单例模式

public class Singleton {
	private static Singleton singleton=null;
	//限制产生多少个对象
	private Singleton(){
	}
	//通过该方法获得对象实例
	public static Singleton getSingleton(){
		if(singleton==null){
			singleton=new Singleton();
		}
		return singleton;
	}
	//类中其它方法,尽量是static
	public static void doSomething(){
	}
}

单例模式的扩展

产生固定数量的皇帝

public class Emperor {
	//固定产生实例数量
	private static int maxNumOfEmperor=2;
	private static ArrayList<String> nameList=new ArrayList<String>();
	private static ArrayList<Emperor> emperorList=new ArrayList<Emperor>();
	//当前皇帝序号
	private static int countNumOfEmperor=0;
	//产生多有对象
	static{
		for(int i=0;i<maxNumOfEmperor;++i){
			emperorList.add(new Emperor("皇"+(i+1)+"帝"));
		}
	}
	
	private Emperor(){
	}
	
	private Emperor(String name){
		nameList.add(name);
	}
	
	public static Emperor getInstance(){
		Random random=new Random();
		countNumOfEmperor=random.nextInt(maxNumOfEmperor);
		return emperorList.get(countNumOfEmperor);
	}
	public void say(){
		System.out.println(nameList.get(countNumOfEmperor));
	}
}

大臣类

public class Minister {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int ministerNum=5;
		for(int i=0;i<ministerNum;++i){
			Emperor emperor=Emperor.getInstance();
			System.out.println("第"+(i+1)+"大臣参拜的是:");
			emperor.say();
		}
	}
}







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值