享元模式学习笔记
一、享元模式
摒弃传统定义,看下面的这个,更好理解。
享元模式(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)