享元模式学习笔记

享元模式学习笔记

一、享元模式

摒弃传统定义,看下面的这个,更好理解。

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。

享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

二、好处和担忧

好处:省内存

担忧:我想持久化这些对象的时候就不好办了,因为输出的这些其实都是同一批对象。

三、享元模式UML

注:自己也不是很理解这个类图为什么要这样话,所以就不放在这里了。有兴趣的请看


四、举例

假设我们要设计一个星空场景,现在我们需要实例星星对象,我们可以实例每一颗星星,但随着我们实例星星对象增多整个场景就越来越慢了,如果你实例了1000+颗星星要你去维护,这可是一个吃力不讨好的工作。事实上,星星类中其他属性是形同的,仅仅是位置不同和半径不同,而颜色就五中。

再比如要绘制如下值班表,实际上只有日期和值班人不同,而星期几也就七中。


五、示例UML

 

六、代码

 

package interfaze;

/**
 * 绘制接口
 * 
 * @author 刘欣普
 *
 */
public interface IDraw {
	void draw();
}

package bean;

import interfaze.IDraw;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 绘制值班表类
 * 
 * @author 刘欣普
 *
 */
public class DrawSchedule implements IDraw {

	// 工具变量,用来格式化日期
	private static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
	// 标记周几
	private int week = 0;
	// 存放日期的变量
	private Date date = new Date();
	// 值班员姓名
	private String ondutyPerson = "";

	@Override
	public void draw() {
		System.out.println("今天是" + DrawSchedule.df.format(this.getDate())
				+ ",星期" + this.getWeek() + "。今天由" + this.getOndutyPerson()
				+ "来值。(我是实例" + this.hashCode() + ")");

	}

	public static SimpleDateFormat getDf() {
		return df;
	}

	public static void setDf(SimpleDateFormat df) {
		DrawSchedule.df = df;
	}

	public int getWeek() {
		return week;
	}

	public void setWeek(int week) {
		this.week = week;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	public String getOndutyPerson() {
		return ondutyPerson;
	}

	public void setOndutyPerson(String ondutyPerson) {
		this.ondutyPerson = ondutyPerson;
	}

}


package bean;

import interfaze.IDraw;

import java.util.HashMap;
import java.util.Map;

/**
 * 生产绘制类的工厂
 * 
 * @author 刘欣普
 *
 */
public class DrawFactory {
	private final static Map<Integer, IDraw> drawMap = new HashMap<Integer, IDraw>();

	public static IDraw getDraw(int week) {
		// 如果drawMap中没有这样的对象就新建一个并添加进去
		if (!DrawFactory.drawMap.containsKey(week)) {
			DrawSchedule tempDraw = new DrawSchedule();
			tempDraw.setWeek(week);
			DrawFactory.drawMap.put(week, tempDraw);
		}
		// 返回已有对象
		return DrawFactory.drawMap.get(week);
	}
}


package test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import bean.DrawFactory;
import bean.DrawSchedule;

public class Test {

	public static void main(String[] args) throws ParseException {
		String[] schedules = { "小白", "小红", "小黑" };
		Date d1 = new SimpleDateFormat("yyyy-MM-DD").parse("2017-3-1");// 定义起始日期
		Date d2 = new SimpleDateFormat("yyyy-MM-DD").parse("2017-3-31");// 定义结束日期
		Calendar c = Calendar.getInstance();// 定义日期实例
		c.setTime(d1);// 设置日期起始时间

		DrawSchedule tempDraw = null;
		while (c.getTime().before(d2)) {// 判断是否到结束日期
			// 获取绘制对象
			tempDraw = (DrawSchedule) DrawFactory.getDraw(c
					.get(Calendar.DAY_OF_WEEK));
			tempDraw.setDate(c.getTime());
			tempDraw.setWeek(c.get(Calendar.DAY_OF_WEEK));
			tempDraw.setOndutyPerson(schedules[(int) (Math.random() * 3)]);
			tempDraw.draw();
			c.add(Calendar.DATE, 1);
		}
	}

}


输出:
今天是2017-01-01,星期1。今天由小黑来值。(我是实例2057221281)
今天是2017-01-02,星期2。今天由小红来值。(我是实例1231353067)
今天是2017-01-03,星期3。今天由小黑来值。(我是实例51090930)
今天是2017-01-04,星期4。今天由小红来值。(我是实例1839285357)
今天是2017-01-05,星期5。今天由小红来值。(我是实例1989380181)
今天是2017-01-06,星期6。今天由小白来值。(我是实例1339801924)
今天是2017-01-07,星期7。今天由小白来值。(我是实例1684897873)
今天是2017-01-08,星期1。今天由小红来值。(我是实例2057221281)
今天是2017-01-09,星期2。今天由小黑来值。(我是实例1231353067)
今天是2017-01-10,星期3。今天由小黑来值。(我是实例51090930)
今天是2017-01-11,星期4。今天由小红来值。(我是实例1839285357)
今天是2017-01-12,星期5。今天由小白来值。(我是实例1989380181)
今天是2017-01-13,星期6。今天由小红来值。(我是实例1339801924)
今天是2017-01-14,星期7。今天由小红来值。(我是实例1684897873)
今天是2017-01-15,星期1。今天由小红来值。(我是实例2057221281)
今天是2017-01-16,星期2。今天由小黑来值。(我是实例1231353067)
今天是2017-01-17,星期3。今天由小红来值。(我是实例51090930)
今天是2017-01-18,星期4。今天由小红来值。(我是实例1839285357)
今天是2017-01-19,星期5。今天由小红来值。(我是实例1989380181)
今天是2017-01-20,星期6。今天由小黑来值。(我是实例1339801924)
今天是2017-01-21,星期7。今天由小黑来值。(我是实例1684897873)
今天是2017-01-22,星期1。今天由小黑来值。(我是实例2057221281)
今天是2017-01-23,星期2。今天由小白来值。(我是实例1231353067)
今天是2017-01-24,星期3。今天由小红来值。(我是实例51090930)
今天是2017-01-25,星期4。今天由小红来值。(我是实例1839285357)
今天是2017-01-26,星期5。今天由小红来值。(我是实例1989380181)
今天是2017-01-27,星期6。今天由小红来值。(我是实例1339801924)
今天是2017-01-28,星期7。今天由小白来值。(我是实例1684897873)
今天是2017-01-29,星期1。今天由小白来值。(我是实例2057221281)
今天是2017-01-30,星期2。今天由小黑来值。(我是实例1231353067)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值