设计模式六大原则(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种设计模式之一)的更多相关文章

  1. Java开发中的23种设计模式详解

    [放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...

  2. Java开发中的23种设计模式详解(转)

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  3. Java开发中的23种设计模式(转)

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  4. c#中的23种设计模式

    C# 23种设计模式汇总 创建型模式 工厂方法(Factory Method) 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节.工厂方法模式的核 ...

  5. Java 23种设计模式

    转自: http://zz563143188.iteye.com/blog/1847029 ; i<count; i++){ list.add(new MailSender()); } } pu ...

  6. 从追MM谈Java的23种设计模式(转)

    从追MM谈Java的23种设计模式    这个是从某个文章转载过来的.但是忘了原文链接.如果知道的,我追加一下. 1.FACTORY-追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西 ...

  7. java 23种设计模式及具体例子 收藏有时间慢慢看

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代 码可靠性. 毫无疑问,设计模式 ...

  8. JAVA:23种设计模式详解(转)

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  9. 从追MM谈Java的23种设计模式

    从追MM谈Java的23种设计模式 1.FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯 德基,只管向服务员说“来四个鸡 ...

  10. 23种设计模式全解析 (java版本)

    转自:http://blog.csdn.net/longyulu/article/details/9159589 其中PHP常用的五种设计模式分别为:工厂模式,单例模式,观察者模式,策略模式,命令模式 ...

随机推荐

  1. HiHoCoder1156 彩色的树(树值的记忆化ORZ+map强势出场)

    1156 : 彩色的树 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定一棵n个节点的树,节点编号为1, 2, …, n.树中有n - 1条边,任意两个节点间恰好有一条 ...

  2. C++11新特性之字节对齐、多参数模版、placement new

    1. 内存对齐 #pragma pack(push, 1) struct A { char a; int b; double c; ]; }; #pragma pack(pop) #pragma pa ...

  3. linux之管道

    1. 进程间通信概述 进程是一个独立的资源分配单元,不同进程之间的资源是独立的,没有关联,不能在一个进程中直接访问另一个进程的资源.进程不是孤立的,不同的进程需要进行信息的交互和状态的传递等,因此需要 ...

  4. Activiti工作流学习之流程图应用详解

    Activiti工作流学习之流程图应用详解 1.目的  了解Activiti工作流是怎样应用流程图的. 2.环境准备2.1.相关软件及版本    jdk版本:Jdk1.7及以上 IDE:eclipse ...

  5. QtAV的编译方法

    1--编译准备 QtAV的安装编译总指导说明:https://github.com/wang-bin/QtAV/wiki/Build-QtAV QtAV的源代码:https://github.com/ ...

  6. 关于bonecp和QuerRunner

    之前一直以为boneCP和QueryRunner是绑定的,但是其实不是,后者来自于commons-dbUtils,BoneCP就是负责连接池. while preparing SQL: UPSERT ...

  7. (转)Android之Adapter用法总结

    1.概念 Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带.在常见的View(ListView,GridView)等地方都需要用到Adapter.如下图直 ...

  8. git 统计命令

    git log --author='user' --pretty=tformat: --numstat --since='2018-01-01' --before='2018-10-10' | gaw ...

  9. mysql实战优化之四:mysql索引优化

    0. 使用SQL提示 用户可以使用use index.ignore index.force index等SQL提示来进行选择SQL的执行计划. 1.支持多种过滤条件 2.避免多个范围条件 应尽量避免在 ...

  10. HDU 3018 Ant Trip(欧拉回路,要几笔)

    Ant Trip Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...