设计模式--享元模式
Cyan
首先学习设计模式的宗旨:将一类不断重复发生、相似的问题以及这类问题的解决方案总结出来,将它们的共同点抽象成一定的模式,以便遇到这类问题,我们可以直接采用这种模式去解决问题。
使用设计模式的误区:不要为了模式而模式,能够在项目中选择最佳设计和实现方案才是王道。设计模式就是一种解决问题的思维。
举个生活中的例子
家里一到晚上就开始抢电视,大人们喜欢看连续剧,小孩喜欢看少儿节目。每天晚上你争我抢的,最后还是输给了小孩,最近看少儿节目,都看的快弱智了!肿么办,摆两台电视吧,一个给小孩看,一个给大人看。一个人用一台电视显得有点浪费,而且家里不一定放得下。按需求来分开两拨,花最少的钱得到所需,更明智些!
官方解释:
它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。
Java中最常见的享元模式
1
2
3
4
5
6
7
|
public class Flyweight{
public static void main(String[] args){
String n = "I Love Java" ;
String m = "I Love Java" ;
System.out.println(n==m);
}
}
|
这段代码会告诉你n==m是true,这就说明了在JVM中n和m两个引用了同一个String对象。String类型的设计避免了在创建N多的String对象时产生的不必要的资源损耗,可以说是享元模式应用的范例。
结构
设计模式:
1)抽象享元角色:为具体享元角色规定了必须实现的方法,而外蕴状态就是以参数的形式通过此方法传入。在Java中可以由抽象类、接口来担当。
2)具体享元角色:实现抽象角色规定的方法。如果存在内蕴状态,就负责为内蕴状态提供存储空间。
3)享元工厂角色:负责创建和管理享元角色。要想达到共享的目的,这个角色的实现是关键!
4)客户端角色:维护对所有享元对象的引用,而且还需要存储对应的外蕴状态。
代码案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
Order:
import java.util.*;
public abstract class Order {
// 执行卖出动作
public abstract void sell();
}
FlavorOrder:
public class FlavorOrder extends Order {
public String flavor;
// 获取咖啡口味
public FlavorOrder(String flavor) {
this .flavor = flavor;
}
@Override
public void sell() {
// TODO Auto-generated method stub
System.out.println( "卖出一份" + flavor + "的咖啡。" );
}
}
FlavorFactory:
public class FlavorFactory {
private Map<String, Order> flavorPool = new HashMap<String, Order>();
// 静态工厂,负责生成订单对象
private static FlavorFactory flavorFactory = new FlavorFactory();
private FlavorFactory() {
}
public static FlavorFactory getInstance() {
return flavorFactory;
}
public Order getOrder(String flavor) {
Order order = null ;
if (flavorPool.containsKey(flavor)) { // 如果此映射包含指定键的映射关系,则返 //回 true
order = flavorPool.get(flavor);
} else {
order = new FlavorOrder(flavor);
flavorPool.put(flavor, order);
}
return order;
}
public int getTotalFlavorsMade() {
return flavorPool.size();
}
}
Client
public class Client {
// 客户下的订单
private static List<Order> orders = new ArrayList<Order>();
// 订单对象生成工厂
private static FlavorFactory flavorFactory;
// 增加订单
private static void takeOrders(String flavor) {
orders.add(flavorFactory.getOrder(flavor));
}
public static void main(String[] args) {
// 订单生成工厂
flavorFactory = FlavorFactory.getInstance();
// 增加订单
takeOrders( "摩卡" );
takeOrders( "卡布奇诺" );
takeOrders( "香草星冰乐" );
takeOrders( "香草星冰乐" );
takeOrders( "拿铁" );
takeOrders( "卡布奇诺" );
takeOrders( "拿铁" );
takeOrders( "卡布奇诺" );
takeOrders( "摩卡" );
takeOrders( "香草星冰乐" );
takeOrders( "卡布奇诺" );
takeOrders( "摩卡" );
takeOrders( "香草星冰乐" );
// 卖咖啡
for (Order order : orders) {
order.sell();
}
// 打印生成的订单java对象数量
System.out.println( "\n客户一共买了 " + orders.size() + " 杯咖啡! " );
// 打印生成的订单java对象数量
System.out.println( "共生成了 " + flavorFactory.getTotalFlavorsMade()
+ " 个 FlavorOrder java对象! " );
}
}
|
Output:
卖出一份摩卡的咖啡。
卖出一份卡布奇诺的咖啡。
卖出一份香草星冰乐的咖啡。
卖出一份香草星冰乐的咖啡。
卖出一份拿铁的咖啡。
卖出一份卡布奇诺的咖啡。
卖出一份拿铁的咖啡。
卖出一份卡布奇诺的咖啡。
卖出一份摩卡的咖啡。
卖出一份香草星冰乐的咖啡。
卖出一份卡布奇诺的咖啡。
卖出一份摩卡的咖啡。
卖出一份香草星冰乐的咖啡。
客户一共买了 13 杯咖啡!
共生成了 4 个 FlavorOrder java对象!
核心总结,可以共享的对象,也就是说返回的同一类型的对象其实是同一实例,当客户端要求生成一个对象时,工厂会检测是否存在此对象的实例,如果存在那么直接返回此对象实例,如果不存在就创建一个并保存起来,这点有些单例模式的意思。通常工厂类会有一个集合类型的成员变量来用以保存对象,如hashtable等。在java中,数据库连接池,线程池等即是用享元模式的应用。
优缺点:
优点:减少对象数量,节省内存空间。
缺点:
1)享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。
2)享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。
设计模式--享元模式相关推荐
- Python设计模式-享元模式
Python设计模式-享元模式 基于Python3.5.2,代码如下 #coding:utf-8class Coffee:name = ""price = 0def __init_ ...
- 10-Python与设计模式--享元模式
10-Python与设计模式--享元模式 一.网上咖啡选购平台 假设有一个网上咖啡选购平台,客户可以在该平台上下订单订购咖啡,平台会根据用户位置进行线下配送.假设其咖啡对象构造如下: class Co ...
- 设计模式--享元模式实现C++
/********************************* *设计模式--享元模式实现 *C++语言 *Author:WangYong *Blog:http://www.cnblogs.co ...
- 【设计模式】Java设计模式 - 享元模式
[设计模式]Java设计模式 - 享元模式
- Unity设计模式——享元模式(附代码)
Unity设计模式--享元模式(附源码) 享元Flyweight模式是什么 享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的 ...
- 第二十二章 Caché 设计模式 享元模式
文章目录 第二十二章 Caché 设计模式 享元模式 定义 优点 使用场景 结构图 描述 完整示例 实体类 抽象享元角色 实现享元角色 享元工厂 调用 思考 第二十二章 Caché 设计模式 享元模式 ...
- JavaScript设计模式-享元模式
JavaScript设计模式-享元模式 概念 例子 内部状态与外部状态 享元模式的通用结构 例子 总结 github仓库地址:点击 [设计模式例子](https://github.com/fanhua ...
- JAVA 设计模式 享元模式
用途 享元模式 (Flyweight) 运用共享技术有效地支持大量细粒度的对象. 享元模式是一种结构型模式. 结构 图-享元模式结构图 Flyweight : 它是所有具体享元类的超类或接口,通过这个 ...
- java设计模式---享元模式
Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己 对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广 泛,遵循一定的编程模式,才能使自己的 ...
- PHP设计模式——享元模式
声明:本系列博客参考资料<大话设计模式>,作者程杰. 享元模式使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件:它适合用于只是因重复而导致使用无法令人接受的大量内存的 ...
最新文章
- C++构造函数(一)
- 77.Linux系统日志,screen工具介绍
- 递归和迭代的区别是什么,各有什么优缺点?
- Android之Android实现浮层的上下滑动(支持内部添加View)
- php配置默认index.php,Apache的vhost中配置默认访问入口index-test.php的方法(Yii)
- 巨杉数据库 CTO 王涛:区块链+数据库,底层技术融合是否带来更大爆发?
- 阿里巴巴Java开发手册中的DO、DTO、BO、AO、VO、POJO定义
- osg渲染到纹理技术(二)
- 689D Magic Odd Square 奇数幻方
- 花书+吴恩达深度学习(九)优化方法之二阶近似方法(牛顿法, CG, BFGS, L-BFGS)
- 一、 zedboardubuntu 14.04 的前期准备(定期更新)
- python有什么用-python有什么用(用处和用途)
- 安装最新LAMP环境(CentOS7+PHP7.1.5+Mysql5.7)
- Java面试八股文(素材来自网络)
- [数据可视化] 饼图(Pie Chart)
- 解决win10微软应用商店打不开的问题
- Emlog模板fee2.0主题商业版
- 十步会用IOCOMP–iplotx控件
- 如何对待每逢佳节被逼婚
- 程序员如何更换证件照背景色