您的位置:首页 > 其它

设计模式笔记之十一 (享元模式)

2013-05-21 15:29 561 查看
享元模式

享元模式的英文说法是:Flyweight Parrern, 又被译作蝇量模式。这两种译法分别说明了其需要解决的问题,解决问题的方式:

当我们需要解决许多轻量类引起的资源开销问题的时候(蝇量模式),我们可以用重用共同点的元素(享元模式)的方法来解决。

正如我们实验室最近接到的一个订单的最终解决方案一样。

前段时间我们的太阳市场部得到一笔大订单:太阳国某富豪要举办一场盛大的聚会,他们需要订购一批女人来满足他的客人们:

class NvRen {
private String name;
private String head;
private String body;
private String type;

public NvRen(String name, String head, String body, String type) {
this.name = name;
this.head = head;
this.body = body;
this.type = type;
}

public void service() {
System.out.println("服务者:" + this.name);
}
}

public class FlyWeight {
public static void main(String[] args) {
int customerNumber = 1000;
String customer = "客人";
for (int i = 0; i < customerNumber; i++) {
String customerName = customer + i;
System.out.print("客人: " + customerName + " 的");
new NvRen("松岛" + i + "子", "瓜子脸", "葫芦型", "气质高雅型").service();
}
}
}


但是当我们准备生产的时候,有个对太阳国比较有研究的技术宅说,据他的了解,在太阳国就算再富有的富豪也找不出一套房子来容纳1000个客人,如果再加上我们的1000个女人产品,肯定连站的地方都没有,更别说躺下或者趴下了。

我们一想也是,到时候那个富豪别一看放不下这么多的人而不定我们的产品了,那就比较尴尬了。

于是我们想到既然没有那么多的地方来容纳那么多的"女人",我们可以少生产一点,反正也没有同时提供service的地方。于是一个新的解决方案出炉了,就是我们提供一个小黑屋,里面只有一个"女人",但是服务不同客户的时候报不同的名字:

class NvRen {
private String name;
private String head;
private String body;
private String type;

public NvRen(String name, String head, String body, String type) {
this.name = name;
this.head = head;
this.body = body;
this.type = type;
}

public void service(String name) {
System.out.println("服务者:" + name);
}
}

class BlackRoom { // 单例的小黑屋
private static BlackRoom br;
private static final Object o = new Object();
private static NvRen nr;

private BlackRoom() {
nr = new NvRen("", "瓜子脸", "葫芦型", "气质高雅型"); // 小黑屋里面只有一个女人的实例
}

public static BlackRoom getInstance() {
if (br == null) {
synchronized (o) {
if (br == null) {
br = new BlackRoom();
}
}
}
return br;
}

public void service(int i) {
String name = "松岛" + i + "子";
nr.service(name);// 小黑屋里面的女人在提供service的时候报不同的名字
}
}

public class FlyWeight {
public static void main(String[] args) {
int customerNumber = 1000;
String customer = "客人";
for (int i = 0; i < customerNumber; i++) {
String customerName = customer + i;
System.out.print("客人: " + customerName + " 的");
BlackRoom.getInstance().service(i);
}
}
}


现在我们只要造一个"女人"就能满足富豪的需求了,而且不会因为地方不够而担心了。

当然,最终我们提供给客户的时候当然不是这么简单的单个产品,我们会提供好几种不同的女人来满足不同客人的需求:

import java.util.HashMap;

class NvRen {
private String name;
private String head;
private String body;
private String type;

public NvRen(String name, String head, String body, String type) {
this.name = name;
this.head = head;
this.body = body;
this.type = type;
}

public void service(String name) {
System.out.println("服务者:" + name + "(真实的女人编码:" + this.hashCode() + ")");
}
}

class BlackRoom { // 单例的小黑屋
private static BlackRoom br;
private static final Object o = new Object();
private static HashMap<String, NvRen> nrs = new HashMap<String, NvRen>();

private BlackRoom() {
// 供客人使用的几种类型
nrs.put("类型1", new NvRen("", "瓜子脸", "葫芦型", "气质高雅型"));
nrs.put("类型2", new NvRen("", "圆脸", "葫芦型", "邻家少女型"));
nrs.put("类型3", new NvRen("", "圆脸脸", "纤细型", "萝莉型"));
nrs.put("类型4", new NvRen("", "瓜子脸", "葫芦型", "御姐型"));
// 专供主人使用的女主人
nrs.put("女主人", new NvRen("", "面饼脸", "纺锤型", "屠夫型"));// 女主人是不共享的
}

public static BlackRoom getInstance() {
if (br == null) {
synchronized (o) {
if (br == null) {
br = new BlackRoom();
}
}
}
return br;
}

public void service(Integer i) {
String name = "";
String type = "";
if (i != null) {
name = "松岛" + i + "子";
type = "类型" + (Math.round(Math.random() * 3) + 1);
} else {
name = "女主人";
type = "女主人";
}
nrs.get(type).service(name); // 小黑屋里面的女人在提供service的时候报不同的名字
}
}

public class FlyWeight {
public static void main(String[] args) {
// 1000个客人
int customerNumber = 1000;
String customer = "客人";
for (int i = 0; i < customerNumber; i++) {
String customerName = customer + i;
System.out.print(customerName + "的");
BlackRoom.getInstance().service(i);
}

System.out.print("主人的");
// 主人
BlackRoom.getInstance().service(null);
}
}


以上就是一个享元模式的应用。当然由于这个模式应用的非常少(本人还没有在项目中用到过),所以如有不当的地方请斧正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: