概述
From Now On,Let us begin Design Patterns。
享元模式
定义
- 采用一个共享来避免大量拥有相同内容对象的开销。这种开销中最常见、直观的就是内存的损耗。享元模式以共享的方式高效的支持大量的细粒度对象。 Use sharing to support large numbers of fine-grained objects efficiently.
(理解举例:享元模式在编辑器系统中大量使用。一个文编辑器往往会提供很多种字体,而通常的做法就是将每一个字母做成一个享元对象。享元对象的内蕴状态就是这个字母,而字母在文本中的位置和字体风格等其他信息则是外蕴状态。比如,字母a可以出现在文本的很多地方,虽然这些字母a的位置和字体风格不同,但是所有这些地方使用的都是同一个字母对象。这样一来,字母对象就可以在整个系统中共享。)
在名字和定义中都体现出了共享这一个核心概念,那么怎么来实现共享呢?要知道每个事物都是不同的,但是又有一定的共性,如果只有完全相同的事物才能共享,那么享元模式可以说就是不可行的;因此我们应该尽量将事物的共性共享,而又保留它的个性。为了做到这点,享元模式中区分了内蕴状态和外蕴状态。内蕴状态就是共性,外蕴状态就是个性了。
通用类图:
角色说明:
Flyweight——抽象享元角色:一个产品的抽象类,同时定义出对象的外部状态和内部状态的接口或实现。
ConcreteFlyweight——具体享元角色:实现抽象角色定义的业务。该角色中需要注意的是内部状态处理应该与环境无关,不应该出现一个操作改变了内部状态,同时修改了外部状态,这是不允许的。
UnsharedConcreteFlyweight——不可共享的享元角色:不存在外部状态或者安全要求(如线程安全)不能够使用共享技术的对象,该对象一般不会出现在享元工厂中。
FlyweightFactory——享元工厂:职责非常简单,就是构造一个池容器,同时提供从池中获得对象的方式
享元模式优点:
大大减少应用程序创建的对象,降低程序内存的占用,增强程序的性能
相同或相似的对象内存只保持一份,极大的节约资源,提高系统性能
外部状态相对独立,不影响内部变化
享元模式的缺点:
提高了系统的复杂性:需要分离出外部状态和内部状态
为了节省内存,共享了内部状态,分离出了外部状态,而读取外部状态使运行时间变长。用时间换空间。
享元模式的使用场景:
内存属于稀缺资源,不能随意浪费。如果在一个系统中有很多个完全相同或相似的对象,我们就可以使用享元模式,让他们共享一份内存即可,不必每个都去实例化对象,从而节省内存空间。
细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份
需要缓冲池的场景
在java中,数据库连接池,线程池等即是用享元模式的应用
注意事项:
享元模式的例子:国际围棋
我摘录网上一个小伙伴写的围棋例子。
每一个围棋棋子都是一个对象,并都有如下属性:
颜色:可以共享的
位置:不可以共享的
围棋代码示例:
FlyWeight抽象享元类:
UnSharedConcreteFlyweight 非共享享元类:棋子坐标
ConcreteFlyWeight具体享元类:具体的围棋类
FlyWeightFactory享元工厂
场景和运行结果:
在Java语言中,String类型就是使用了享元模式。String对象是final类型,对象一旦创建就不可改变。在JAVA中字符串常量都是存在常量池中的,JAVA会确保一个字符串常量在常量池中只有一个拷贝。String a=”abc”,其中”abc”就是一个字符串常量。
享元对象能做到共享的关键是区分了内部状态和外部状态。
内部状态:可以共享,不会随环境改变而改变。
外部状态:不可以共享,会随环境改变而改变。
最后
以上就是认真太阳为你收集整理的设计模式(13) 享元模式(简单入门 结构模式)的全部内容,希望文章能够帮你解决设计模式(13) 享元模式(简单入门 结构模式)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复