FlyweightPattern(23种设计模式之一)
设计模式六大原则(1):单一职责原则
设计模式六大原则(2):里氏替换原则
设计模式六大原则(3):依赖倒置原则
设计模式六大原则(4):接口隔离原则
设计模式六大原则(5):迪米特法则
设计模式六大原则(6):开闭原则
参考书籍:设计模式-可复用面向对象软件基础(黑皮书)
享元模式,以共享的方式高效地支持大量的细粒度对象。通过复用内存中已存在的对象,降低系统创建对象实例的性能消耗。
简单的典型实例:以黑白五子棋对弈为例,获取每个棋子的状态,然而我们不可能为每个棋子都建立一个对象,这样内存开销太大,这样关键就在于抽象出每个棋子的内部状态和外部状态,将其的状态分离。
FlyweightPattern,UML抽象图百度找,代码实现如下
使用享元模式设计以黑白五子棋对弈
抽象细粒度对象类
package FlyweightPattern;
public abstract class Chessman {
private String color;
private int x;
private int y;
public Chessman(String color){
this.color = color;
}
public void setPosition(int x,int y){
this.x = x;
this.y = y;
}
public String getColor(){
return color;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
细粒度具体对象类
package FlyweightPattern;
public class BlackChessman extends Chessman {
public BlackChessman() {
super("黑棋子");
System.out.println("创建黑棋子");
}
}
package FlyweightPattern;
public class WhiteChessman extends Chessman {
public WhiteChessman() {
super("白棋子");
System.out.println("创建白棋子");
}
}
粒度工厂类
package FlyweightPattern;
import java.util.Hashtable;
public class ChessmanFactory {
private static ChessmanFactory chessmanFactory = new ChessmanFactory();
//缓存存放共享对象
Hashtable<Character,Chessman> cache = new Hashtable<Character,Chessman>();
public static ChessmanFactory getInstance(){
return chessmanFactory;
}
//获取棋子
public Chessman getChessman(char c){
Chessman chessman = this.cache.get(c);
if(chessman==null){
if(c=='W'){
chessman = new WhiteChessman();
}else if(c=='B'){
chessman = new BlackChessman();
}
cache.put(c, chessman);
}
return chessman;
}
}
测试类
package FlyweightPattern;
public class Test {
public static void main(String[] args) {
ChessmanFactory factory=ChessmanFactory.getInstance();
Chessman chessman1=factory.getChessman('W');
chessman1.setPosition(1, 1);
System.out.println(chessman1.getColor()+" ("+chessman1.getX()+","+chessman1.getY()+")");
Chessman chessman2=factory.getChessman('W');
chessman2.setPosition(2, 2);
System.out.println(chessman2.getColor()+" ("+chessman2.getX()+","+chessman2.getY()+")");
Chessman chessman3=factory.getChessman('B');
chessman3.setPosition(3, 3);
System.out.println(chessman3.getColor()+" ("+chessman3.getX()+","+chessman3.getY()+")");
Chessman chessman4=factory.getChessman('B');
chessman4.setPosition(4, 4);
System.out.println(chessman4.getColor()+" ("+chessman4.getX()+","+chessman4.getY()+")");
}
}
享元模式的两种状态:内蕴状态和外蕴状态
1.内蕴状态(内部状态):
享元模式的内蕴状态是不会随环境的改变而改变的,是存储在享元对象内部的状态信息,因此内蕴状态是可以共享的,对于任何一个享元对象来讲,它的值是完全相同的。就像上面例子中的“黑子”和“白子”,它代表的状态就是内蕴状态。
2.外蕴状态(外部状态)
外蕴状态会随环境的变化而改变的,因此是不可共享的状态,对于不同的享元对象来讲,它的值可能是不同的。享元对象的外蕴状态必须由客户端保存,在享元对象被创建之后,需要使用的时候再传入到享元对象的内部。就像五子棋的位置信息,代表的状态就是享元对象的外蕴状态。
享元模式关键就在内部状态与外部状态的分离,在这里,场景就是棋盘,棋子的坐标就是外部状态(不可共享),棋子的颜色就是独立于场景的内部状态(可被共享),用户对象负责在有必要的时候将外部状态传递给享元
FlyweightPattern(23种设计模式之一)的更多相关文章
- Java开发中的23种设计模式详解
[放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...
- Java开发中的23种设计模式详解(转)
设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- Java开发中的23种设计模式(转)
设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- c#中的23种设计模式
C# 23种设计模式汇总 创建型模式 工厂方法(Factory Method) 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节.工厂方法模式的核 ...
- Java 23种设计模式
转自: http://zz563143188.iteye.com/blog/1847029 ; i<count; i++){ list.add(new MailSender()); } } pu ...
- 从追MM谈Java的23种设计模式(转)
从追MM谈Java的23种设计模式 这个是从某个文章转载过来的.但是忘了原文链接.如果知道的,我追加一下. 1.FACTORY-追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西 ...
- java 23种设计模式及具体例子 收藏有时间慢慢看
设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代 码可靠性. 毫无疑问,设计模式 ...
- JAVA:23种设计模式详解(转)
设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- 从追MM谈Java的23种设计模式
从追MM谈Java的23种设计模式 1.FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯 德基,只管向服务员说“来四个鸡 ...
- 23种设计模式全解析 (java版本)
转自:http://blog.csdn.net/longyulu/article/details/9159589 其中PHP常用的五种设计模式分别为:工厂模式,单例模式,观察者模式,策略模式,命令模式 ...
随机推荐
- CTF学习资料总结
网络攻防大作业学习方向思路 一直对CTF比赛有参与的兴趣,但由于课程比较多,一直没有足够的时间系统的去了解与训练.所以我想利用接下来的几周时间对CTF比赛经行练习.并找到自己所擅长或感兴趣的方向深入研 ...
- 洛谷 P1262 间谍网络
传送门 题目大意:A能揭发B,B能揭发C..某些人可以被收买,如果收买A,那么A,B,C..的情报都可以得到. 求能否得到所有情报,如果可以最少花费多少钱去收买. 题解:tajian缩点 dfs/bf ...
- Biology(湖南集训)
题目大意:n个字符串,m个操作,可以插入字符串,也可以询问某T个字符串的最长后缀 题解:Trie+lca Trie树的插入与查询操作.把字符串反转就相当于求公共前缀. lca的深度就是公共前缀的长度. ...
- 对Servlet规范的蜻蜓点水
现在我们大家基本都用struts或springmvc进行java web的开发,但我们都知道java web的核心技术是jsp servlet javabean的组合.因此很有必要知道servlet规 ...
- 不得不注意tornado多进程部署的副作用
tornado多进程启动时,采用的是fork的方式. 一个现有进程可以调用fork函数创建一个新进程.由fork创建的新进程被称为子进程(child process).fork函数被调用一次但返回两次 ...
- 重写struts过滤器
<filter> <filter-name>ExtendStrutsFilter</filter-name> <filter-class& ...
- [转]json-lib 的maven dependency
转载自http://www.cnblogs.com/yqskj/archive/2013/05/27/3101934.html 项目中要用到json-lib,mvnrepository.com查找它的 ...
- Eclipse执行import命令导入maven项目时报错:Add a version or custom suffix using "Name template" in "Advanced" settings
新建了两个maven项目在E盘workspace目录,后面移到workspace/app_engine目录下提交svn,再通过Eclipse的File->import导入时报错了: Projec ...
- PHP面向对象深入研究之【对象生成】
对象 看个例子 <?php abstract class Employee { // 雇员 protected $name; function __construct( $name ) { $t ...
- 巧妙的运用group,count,order有利于统计
$aAwardMem = $this->dao_raward->getAwardAndMem($where,array('award_cat asc','award_level asc') ...