`

Java设计模式之单例(Singleton)与享元(Flyweight)

阅读更多
很久之前就阅读过GoF的设计模式,由于才疏学浅,又没有什么实践经验,完全是一个学生的走马观花。现在由于在实际工作中的需要,还是要一遍遍反复回味这些优秀的设计模式,正所谓温故而知新。
首先来说一说单例(Singleton)模式,我想这是非常容易理解的一种设计模式。所谓单例,就是要求在应用运行过程中,只存在某个类的一个实例,所有其它对象都只可能引用到这一个实例。为何要有单例模式,有一种说法是:节省内存。这个观点,不能说它是错误的,因为单例确实可以做到这一点,但这并不是单例模式出现的本因。我认为,单例模式是为了处理某些逻辑问题的。比如说,某个类,如果同时存在多个实例,就可能引发逻辑错误。比如一个计数类,负责对每一次web请求计数,假如多个实例同时出现,逻辑上就会发生错误。因为每一个实例都不能真实的反映访问量。

实现单例模式,也很简单,我们常见到的方式如下:
public class Singleton{
    private static Singleton instance = null;
    //一些其它数据域
    
    private Singleton(){
    }
    public static Singleton getInstance(){
        if(instance == null)
              instance = new Singleton();
        return instance;
    }
}

这段代码的特殊之处:
1. 自己持有一个对自己引用的静态数据域
2. 私有构造函数
3. 通过静态getInstance()获得实例

正是由于以上的3点,才能保证单例不会被以new的方式得到,只能通过静态方法获得。
上面的这段代码,存在这一个隐患:
它并不是线程安全的,当面对一个并发访问的应用环境中时,有可能会出现2个实例。
比如,线程A执行到insta = new...时,此时,instance还没有得到真实的引用,此时线程B再次判断,发现instance仍是null,将会有一次创建新的实例。
下面我们将展示上述隐患:

public class Singleton {
	private static Singleton instance = null;
	private static int count=0;//记录被创建实例的总数
	private int id;//当前实例的id
	
	private Singleton(){
		count++;
		id = count;
	}
	public static Singleton getInstance(){
		if(instance==null){
			instance = new Singleton();
		}
		return instance;
	}
	public int getId() {
		return id;
	}
}


简单的测试线程

public class TestThread implements Runnable {


	public void run() {
		// TODO Auto-generated method stub
		Singleton myInstance = Singleton.getInstance();
		System.out.println(myInstance.getId()+"th instance is created.");

	}

}

Main函数:
public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TestThread threadA = new TestThread();
		TestThread threadB = new TestThread();
		new Thread(threadA).start();
		new Thread(threadB).start();

	}

}

结果:
在上述条件下,结果具有不确定性,与线程的调度有一定关系,所以,有时会创建一个实例,有时会创建两个实例:
1th instance is created.
1th instance is created.
-----------
2th instance is created.
1th instance is created.
-----------
1th instance is created.
2th instance is created.
下面,我们将getInstance方法声明成为synchronized的,运行结果始终是:
1th instance is created.
1th instance is created.
==================================================
享元模式   对于享元模式的认识,也是刚刚开始。享元来自于拳击术语,即轻量级(flyweight),意指面向对象程序设计中很多粒度很小的类。这些类具备这样的特点:它的某些属性或行为,与其它的类呈现包容关系。而且这些类的状态的变化,也是直接反映到所有包容它的类类中。就是说,这些类是可以被share的,所以称之为享元(共享的单元??)。
一个典型的例子,我觉得就是编辑器与文字的关系,26个英文字母,即可作为享元来使用。
那么,它会被哪些类共享呢?我们可以考虑由一个font类,那么,一个编辑器有很多种字体,字体有颜色 大小之类的属性,也有字母的值(a,b,c...),那么把这些字母的值和其固有的一些方法抽象出来作为享元。
也许你可能会觉得,不就是一个char的字符值么,有必要抽象成一个类么。但是,如果你有一个几百万个字母的文章需要处理,那么100w*sizeof(char)>>26*sizeof(char)+othercost的。

至于其它的应用场景,需要在现实应用中自己来思考抽象了。具体的实现也不再多谈,可以上网搜索。
分享到:
评论

相关推荐

    Java面试 java设计模式整理 单例、工厂、策略等 面试使用,学习使用

    12.享元模式(Flyweight) 9 13.模板模式 9 13、策略模式(strategy) 12 14、模板方法模式(Template Method) 13 15、观察者模式(Observer) 14 16、迭代子模式(Iterator) 16 17、责任链模式(Chain of ...

    [Java设计模式(第2版)(Design.Patterns.in.Java).John.Metsker

    《java设计模式(第2版)》通过一个完整的java项目对经典著作design patterns一书介绍的23种设计模式进行了深入分析与讲解,实践性强,却又不失对模式本质的探讨。本书创造性地将这些模式分为5大类别,以充分展现各个...

    33种JAVA设计模式DEMO

    享元模式(Flyweight Pattern) 代理模式(Proxy Pattern) 3 行为型模式 这些设计模式特别关注对象之间的通信。 责任链模式(Chain of Responsibility Pattern) 命令模式(Command Pattern) 解释器模式...

    用Java实现23种设计模式

    用Java实现23种设计模式 1. 创建型模式 工厂模式(Factory Pattern) 抽象工厂模式(Abstract Factory Pattern) 单例模式(Singleton Pattern) 建造者模式(Builder Pattern) 原型模式(Prototype Pattern)...

    Java设计模式,并加上个人理解

    1. 设计模式 1.1 含义 1.2 作用 1.3 设计原则 1.4 分类 2. 简单工厂模式 (SimpleFactoryPattern) ...15. 享元模式 (Flyweight Pattern) 16. 桥接模式 (Bridge Pattern) 17. 观察者模式 (Observer Pattern)

    23种java版设计模式源码案例.zip

    23种java版设计模式源码案例.zip 0.目录 创建型模式(creational) 简单工厂(simplefactory) 动态工厂(dynamic) 抽象工厂(abstract) 单例模式(singleton) 建造者模式(builder) 原型模式(prototype) 结构型模式...

    java26个设计模式

    工厂模式Factory 原始Prototype 单例Singleton 建造Builder 多例Multiton 适配器Adepter 装饰Decorator 合成Composite 代理Proxy 享元Flyweight 门面Facade 桥梁Bridge 不变Immutable 策略Strategy 模版Template ...

    java版本二十三种设计模式.zip

    - 享元模式(Flyweight) - 观察者模式(Observer) - 模板方法模式(Template Method) - 策略模式(Strategy) - 责任链模式(Chain of Responsibility) - 中介者模式(Mediator) - 访问者模式(Visitor) - 命令模式...

    Java高手真经 - Java Web系统设计与架构 源代码(一)设计模式

    Java高手真经 - Java Web系统设计与架构 源代码(一)设计模式 (3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1...

    java之23种设计模式

    设计模式之Java实现源码,其中包含三大类,23种,分别为创建型 1. Factory Method(工厂方法) 2. Abstract Factory(抽象工厂) 3. Builder(建造者) 4. Prototype(原型) 5. Singleton(单例) 结构型 6. ...

    design-pattern-java.pdf

    实现对象的复用——享元模式(二) 实现对象的复用——享元模式(三) 实现对象的复用——享元模式(四) 实现对象的复用——享元模式(五) 代理模式-Proxy Pattern 设计模式之代理模式(一) 设计模式之代理模式...

    [源代码] 《易学 设计模式》 随书源代码

    第15章 源源不断:享元模式 (Flyweight) 第16章 按部就班:模板方法模式 (TemplateMethod) 第17章 风吹草动:观察者模式 (Observer) 第18章 变化多端:状态模式 (State) 第19章 明修栈道,暗度陈仓:策略模式 ...

    研磨设计模式-part2

    第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor) ...

    研磨设计模式-part4

    第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor) ...

    研磨设计模式-part3

    第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor) ...

    源码:阎宏设计模式光盘

    com.javapatterns.flyweight 享元模式 com.javapatterns.immutable 不变模式 com.javapatterns.interfaces Java接口 com.javapatterns.interpreter 解释器模式 com.javapatterns.isp 接口隔离原则 ...

    超市管理系统java源码swing-king-design:23种java设计模式

    享元模式(flyweight) 代理模式(proxy) 行为型模式(behaviour) 责任链模式(chainrespon) 命令模式(commond) 解释器模式(interpreter) 迭代器模式(iterator) 中介者模式(mediator) 备忘录模式(memento) 观察者模式...

    二十三种设计模式【PDF版】

    设计模式之 Singleton(单态/单件) 阎宏博士讲解:单例(Singleton)模式 保证一个类只有一个实例,并提供一个访问它的全局访问点 设计模式之 Factory(工厂方法和抽象工厂) 使用工厂模式就象使用 new 一样频繁. ...

    java设计模式

    11. Flyweight(享元) 12. Proxy(代理) 行为型 13. Interpreter(解释器) 14. Template Method(模板方法) 15. Chain of Responsibility(责任链) 16. Command(命令) 17. Iterator(迭代器) 18. ...

    单例模式源码java-DesignPattern:在个人自学阶段的23种设计模式代码的全部实现,全部使用Java编写,其中还包括各个设计模式在

    在个人自学阶段的23种设计模式代码的全部实现,全部使用Java编写,其中还包括各个设计模式在源码中的使用,每种设计模式都举了一个简单的小例子来进行实现,并加以注释 包名解释 一、DesignPattern 1.1 创建型模式 ...

Global site tag (gtag.js) - Google Analytics