享元模式
2016-04-08 16:13
218 查看
原理:
运用共享技术有效地支持大量细粒度的对象。
不使用享元模式:
内部状态与外部状态
(1)上述代码实现了享元模式共享的目的,无论几个用户,运行游戏一样,就只保留一个游戏逻辑代码。
(2)但是,这些用户毕竟不是同一个用户,用户名不同,用户的牌也不同。
(3)我们称享元对象内部不随环境变化的共享部分称为内部状态。
(4)而随环境而改变,不可以共享的称为外部状态。
享元模式的优点在于它大幅度地降低内存中对象的数量。但是,它做到这一点所付出的代价也是很高的,享元模式使得系统更加复杂。
为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。
应用:
享元模式在编辑器软件中大量使用,如在一个文档中多次出现相同的图片,则只需要创建一个图片对象,通过在应用程序中设置该图片出现的位置,可以实现该图片在不同地方多次重复显示。
运用共享技术有效地支持大量细粒度的对象。
不使用享元模式:
class Game //游戏 { private string name = ""; public Game(string name) { this.name = name; } public void Play() { Console.WriteLine("运行游戏:" + name); } } static void Main(string[] args) { Game zs = new Game("斗地主"); zs.Play(); Game ls = new Game("斗地主"); ls.Play(); Game ww = new Game("斗地主"); ww.Play(); Game zl = new Game("麻将"); zl.Play(); Game sq = new Game("麻将"); sq.Play(); Game zb = new Game("麻将"); zb.Play(); Console.Read(); }三个斗地主实例,本质都是一样的代码,但是随着用户增多,实例也会增多,对服务器资源造成浪费,希望共享代码
abstract class Game //游戏 { public abstract void Play(); } //具体的游戏 class ConcreteGame : Game { private string name = ""; public ConcreteGame(string name) { this.name = name; } public override void Play() { Console.WriteLine("运行游戏:" + name); } } class GameFactory //游戏工厂 { private Hashtable flyweights = new Hashtable(); //获得游戏分类 public Game GetGameCategory(string key) { if (!flyweights.ContainsKey(key)) flyweights.Add(key, new ConcreteGame(key)); return ((Game)flyweights[key]); } //获得游戏分类总数 public int GetGameCount() { return flyweights.Count; } } static void Main(string[] args) { GameFactory f = new GameFactory(); Game zs = f.GetGameCategory("斗地主"); zs.Play(); Game ls = f.GetGameCategory("斗地主"); ls.Play(); Game ww = f.GetGameCategory("斗地主"); ww.Play(); Game zl = f.GetGameCategory("麻将"); zl.Play(); Game sq = f.GetGameCategory("麻将"); sq.Play(); Game zb = f.GetGameCategory("麻将"); zb.Play(); Console.WriteLine("游戏逻辑总数为 {0}", f.GetGameCount()); Console.Read(); }
内部状态与外部状态
(1)上述代码实现了享元模式共享的目的,无论几个用户,运行游戏一样,就只保留一个游戏逻辑代码。
(2)但是,这些用户毕竟不是同一个用户,用户名不同,用户的牌也不同。
(3)我们称享元对象内部不随环境变化的共享部分称为内部状态。
(4)而随环境而改变,不可以共享的称为外部状态。
//用户 public class User { private string name; public User(string name) { this.name = name; } public string Name { get { return name; } } } abstract class Game //游戏 { public abstract void Play(User user); } //具体的游戏 class ConcreteGame : Game { private string name = ""; public ConcreteGame(string name) { this.name = name; } public override void Play(User user) { Console.WriteLine("运行游戏:" + name + " 用户:" + user.Name); } } static void Main(string[] args) { GameFactory f = new GameFactory(); Game zs = f.GetGameCategory("斗地主"); zs.Play(new User("张三")); Game ls = f.GetGameCategory("斗地主"); ls.Play(new User("李四")); Game ww = f.GetGameCategory("斗地主"); ww.Play(new User("王五")); Game zl = f.GetGameCategory("麻将"); zl.Play(new User("赵六")); Game sq = f.GetGameCategory("麻将"); sq.Play(new User("孙七")); Game zb = f.GetGameCategory("麻将"); zb.Play(new User("周八")); Console.WriteLine("游戏逻辑总数为 {0}", f.GetGameCount()); Console.Read(); }优缺点:
享元模式的优点在于它大幅度地降低内存中对象的数量。但是,它做到这一点所付出的代价也是很高的,享元模式使得系统更加复杂。
为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。
应用:
享元模式在编辑器软件中大量使用,如在一个文档中多次出现相同的图片,则只需要创建一个图片对象,通过在应用程序中设置该图片出现的位置,可以实现该图片在不同地方多次重复显示。
相关文章推荐
- 简单说说TCP(2) --- 数据传输
- 自制BaseServlet
- 你想建设一个能承受500万PV/每天的网站吗?
- UVA_104_Arbitrage
- 欧拉环、欧拉路径的判定和求法
- 面试问题,将字符串、字符串单词倒叙输出
- 泛型依赖注入
- WKNavigationDelegate调用的顺序
- Hadoop和spark通信机制
- 在竞赛ACM Java处理输入输出
- linux下安装mongodb3.2.4
- 数组分段查找
- css 相对电脑窗口定位
- Service详解(五):使用Messager进行通信
- 【笔记】 《js权威指南》- 第17章 事件处理 - 17.2 - 17.3
- C语言之数组冒泡排序方法(学习之路)
- C++之运算符重载
- MySql远程不能登录问题解决办法
- 两个一维数组合并为对应的二维数组(array_merge_recursive)
- Netty1——概况