- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java设计模式之享元模式由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文介绍了java设计模式之享元模式,供大家参考,具体内容如下 。
1、关于享元模式 。
享元模式有点类似于单例模式,都是只生成一个对象被共享使用。享元模式主要目的就是让多个对象实现共享,减少不会要额内存消耗,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗.
2、享元模式结构图 。
因为享元模式结构比较复杂,一般结合工厂模式一起使用,在它的结构图中包含了一个享元工厂类.
在享元模式结构图中包含如下几个角色:
flyweight(抽象享元类):通常是一个接口或抽象类,在抽象享元类中声明了具体享元类公共的方法,这些方法可以向外界提供享元对象的内部数据(内部状态),同时也可以通过这些方法来设置外部数据(外部状态).
concreteflyweight(具体享元类):它实现了抽象享元类,其实例称为享元对象;在具体享元类中为内部状态提供了存储空间。通常我们可以结合单例模式来设计具体享元类,为每一个具体享元类提供唯一的享元对象.
unsharedconcreteflyweight(非共享具体享元类):并不是所有的抽象享元类的子类都需要被共享,不能被共享的子类可设计为非共享具体享元类;当需要一个非共享具体享元类的对象时可以直接通过实例化创建.
flyweightfactory(享元工厂类):享元工厂类用于创建并管理享元对象,它针对抽象享元类编程,将各种类型的具体享元对象存储在一个享元池中,享元池一般设计为一个存储“键值对”的集合(也可以是其他类型的集合),可以结合工厂模式进行设计;当用户请求一个具体享元对象时,享元工厂提供一个存储在享元池中已创建的实例或者创建一个新的实例(如果不存在的话),返回新创建的实例并将其存储在享元池中.
3、享元模式的实现 。
在享元模式中引入了享元工厂类,享元工厂类的作用在于提供一个用于存储享元对象的享元池,当用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象.
接下来,实现一个登陆的享元模式.
1、用户类 。
。
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
|
/**
* 用户类
* @author 董秀才
*
*/
public
class
user {
private
string username;
// 用户名
private
string password;
// 密码
public
user(string username,string password) {
this
.username = username;
this
.password = password;
}
public
string getusername() {
return
username;
}
public
void
setusername(string username) {
this
.username = username;
}
public
string getpassword() {
return
password;
}
public
void
setpassword(string password) {
this
.password = password;
}
}
|
2、抽象的登陆者(抽象享元类) 。
1
2
3
4
5
6
7
8
9
10
11
|
/**
* 登陆者--抽象享元类
* @author 董秀才
*
*/
public
abstract
class
loginer {
//登陆--享元类公共方法
public
abstract
void
login(user user);
}
|
3、具体的登陆者(具体享元类) 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/**
* 具体享元类
* @author 董秀才
*
*/
public
class
concreteloginer
extends
loginer{
// 登陆者凭证
private
string loginerkey =
""
;
public
concreteloginer(string loginerkey) {
this
.loginerkey = loginerkey;
}
@override
public
void
login(user user) {
system.out.println(
"登陆者凭证:"
+
this
.loginerkey+
",用户名:"
+ user.getusername() +
",密码:"
+ user.getpassword());
}
}
|
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
|
/**
* 享元工厂类
* @author 董秀才
*
*/
public
class
concreteloginerfactory {
// map充当对象享元池
private
static
map<string,concreteloginer> loginermap =
new
hashmap<string, concreteloginer>();
public
static
concreteloginer getconcreteloginer(string key) {
// 从享元池中拿 登陆者对象
concreteloginer concreteloginer = loginermap.get(key);
// 如果享元池中没有此对象
if
(concreteloginer ==
null
) {
// 创建对象
concreteloginer =
new
concreteloginer(key);
// 存到享元池中
loginermap.put(key, concreteloginer);
}
// 返回对象
return
concreteloginer;
}
// 返回享元池对象数量
public
static
int
getsize() {
return
loginermap.size();
}
}
|
5、测试类 。
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
|
/**
* 博客测试类
* @author 董秀才
*
*/
public
class
maintest {
public
static
void
main(string[] args) {
// 去工厂拿对象
concreteloginer concreteloginer_1 = concreteloginerfactory.getconcreteloginer(
"csdn"
);
concreteloginer_1.login(
new
user(
"董秀才"
,
"123456"
));
concreteloginer concreteloginer_2 = concreteloginerfactory.getconcreteloginer(
"csdn"
);
concreteloginer_2.login(
new
user(
"董秀才"
,
"123456"
));
concreteloginer concreteloginer_3 = concreteloginerfactory.getconcreteloginer(
"csdn"
);
concreteloginer_3.login(
new
user(
"董秀才"
,
"123456"
));
// 测试是否是同一个对象
system.out.println(
"是否是同一个对象:"
+ ((concreteloginer_1==concreteloginer_2)&&(concreteloginer_2 == concreteloginer_3)));
// 第二登陆者
concreteloginer concreteloginer_4 = concreteloginerfactory.getconcreteloginer(
"博客园"
);
concreteloginer_4.login(
new
user(
"董才才"
,
"654321"
));
concreteloginer concreteloginer_5 = concreteloginerfactory.getconcreteloginer(
"博客园"
);
concreteloginer_5.login(
new
user(
"董才才"
,
"654321"
));
concreteloginer concreteloginer_6 = concreteloginerfactory.getconcreteloginer(
"博客园"
);
concreteloginer_6.login(
new
user(
"董才才"
,
"654321"
));
system.out.println(
"是否是同一个对象:"
+ ((concreteloginer_4==concreteloginer_5)&&(concreteloginer_5 == concreteloginer_6)));
// 工厂类中享元池中对象数量
system.out.println(
"享元池size:"
+ concreteloginerfactory.getsize());
}
}
|
6、运行结果 。
4、总结 。
从上面代码和运行结果这可以看到,同一个登陆者登陆时是 "享" 用同一个登陆者对象。在享元对象池中只有两个对象.
享元模式优点 。
享元模式的外部状态相对独立,使得对象可以在不同的环境中被复用(共享对象可以适应不同的外部环境) 。
享元模式可共享相同或相似的细粒度对象,从而减少了内存消耗,同时降低了对象创建与垃圾回收的开销 。
享元模式缺点 。
外部状态由客户端保存,共享对象读取外部状态的开销可能比较大 。
享元模式要求将内部状态与外部状态分离,这使得程序的逻辑复杂化,同时也增加了状态维护成本 。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://www.cnblogs.com/dongxiucai/p/9460069.html 。
最后此篇关于Java设计模式之享元模式的文章就讲到这里了,如果你想了解更多关于Java设计模式之享元模式的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!