设计模式六大原则(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. 快速沃尔什变换FWT

    快速沃尔什变换\(FWT\) 是一种可以快速完成集合卷积的算法. 什么是集合卷积啊? 集合卷积就是在集合运算下的卷积.比如一般而言我们算的卷积都是\(C_i=\sum_{j+k=i}A_j*B_k\) ...

  2. LeetCode Minimum Time Difference

    原题链接在这里:https://leetcode.com/problems/minimum-time-difference/description/ 题目: Given a list of 24-ho ...

  3. LG3374 【模板】树状数组 1

    题意 如题,已知一个数列,你需要进行下面两种操作: 将某一个数加上x 求出某区间每一个数的和 对于100%的数据:N<=500000,M<=500000 分析 cdq分治解决,参照mlys ...

  4. JS、Jquery获取浏览器和屏幕各种高度宽度

    网页可见区域宽:document.body.clientWidth网页可见区域高:document.body.clientHeight网页可见区域宽:document.body.offsetWidth ...

  5. EXCEL类型库的添加

    1. 创建新的C++工程 创建基于对话框的MFC程序 2. 添加库.添加Excel类库 在工程名上右键,选择“添加”—“类”(或者点击菜单栏的“项目”->“添加类”),选择“TypeLib中的M ...

  6. PhysicalDrive

    由于"\"是C/C+中转义符, "\\\\.\\"就相当于\\.\ 在Windows中 \\.\ 前缀用于标识设备,其中的"."表示本地计算 ...

  7. 解决eclipse Blocked : the user operation is waiting

    本文转载自:http://blog.csdn.net/shaw1994/article/details/44106679 出现这种情况的时候整个adb都跪了, eclipse一run就会跪, 而且还容 ...

  8. 庖丁解牛-----Live555源码彻底解密(根据MediaServer讲解Rtsp的建立过程)

    live555MediaServer.cpp服务端源码讲解 int main(int argc, char** argv) { // Begin by setting up our usage env ...

  9. java代码-----------java中的windowAdapter的实例

    总结:我知道他是一专多能型.很优秀~~~~~~~~~~~.好幸福啊 package com.a.b; import java.awt.Color; import java.awt.event.Wind ...

  10. redis基本操作和在springboot中的使用

    本文介绍redis的使用 redis启动步骤 说明 redis自增自减相关操作 redis string set操作 get操作 其他操作 redis hash set操作 get操作 其他操作 re ...