写点什么

设计模式 -- 享元模式

发布于: 2021 年 03 月 30 日

概述


- 享元模式是以共享的方式高效地支持大量的细粒度对象。

- 享元对象能做到共享的关键是==区分内部状态和外部状态==。内部状态是存储在享元对象内部并且不会随环境改变而改变。因此内部状态可以共享。


享元模式结构图

示意性代码


namespace 享元模式{    abstract class Flyweight    {        public abstract void Operation(int extrinsicstate);    }
class ConcreteFlyweight:Flyweight { public override void Operation(int extrinsicstate) { Console.WriteLine("具体Flyweight:" + extrinsicstate); } }
class UnsharedConcreteFlyweight:Flyweight { public override void Operation(int extrinsicstate) { Console.WriteLine("不共享的具体Flyweight:" + extrinsicstate); } }
class FlyweightFactory { private Hashtable flyweights = new Hashtable();
public FlyweightFactory() { flyweights.Add("X", new ConcreteFlyweight()); flyweights.Add("Y", new ConcreteFlyweight()); flyweights.Add("Z", new ConcreteFlyweight()); }
public Flyweight GetFlyweight(string key) { return (Flyweight)flyweights[key]; } } class Program { static void Main(string[] args) { int extrinsicstate = 22;
FlyweightFactory f = new FlyweightFactory();
Flyweight fx = f.GetFlyweight("X"); fx.Operation(--extrinsicstate);
Flyweight fy = f.GetFlyweight("Y"); fx.Operation(--extrinsicstate);
Flyweight fz = f.GetFlyweight("Z"); fx.Operation(--extrinsicstate);
UnsharedConcreteFlyweight uf = new UnsharedConcreteFlyweight();
uf.Operation(--extrinsicstate);
Console.Read(); } }}
复制代码


享元模式重点

==共享内部状态,加载外部状态==

变与不变


- 享元模式设计的重点就在==分离变与不变==。把一个对象的状态分成内部状态的外部状态,==内部状态是不变的,外部状态是可变的==。然后通过共享不变的部分,达到减少对象数量并节约内存的目的。

- 分离变与不变是软件设计上最基本的方式之一,比如预留接口:一个常见的原因就是这里存在变化,可能在今后需要扩展或者是改变已有的实现,因此预留接口作为“==可插入性的保证==”。

享元模式使用情况

- 一个系统有大量的对象。

- 这些对象耗费大量的内存

- 这些对象的状态中的大部分都可以外部消化。

- 这些对象可以按照内部状态分成很多的组,当把外部对象从对象中剔除时,每一个组都可以仅用一个对象代替。


使用享元模式需要维护一个记录了系统已有的所有享元的表,而这需要耗费资源。因此,应当在有足够多的享元实例可供共享时才值得使用享元模式。


优点

大幅度地降低内存中对象的数量,节省内存空间

缺点


- 享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。

- 享元模式将向原对象的状态外部化,而读取外部状态使得运行时间变长。


本质

分离与共享


实例

ps:仅代表个人思路

【问题】

使用享元模式实现五子棋

【代码】


public class Location {		private int x,y;	private String color;
public Location(int x, int y,String color) { super(); this.x = x; this.y = y; this.color=color; }
public Location() {}
public int getX() { return x; }
public void setX(int x) { this.x = x; }
public int getY() { return y; }
public void setY(int y) { this.y = y; } public String getColor() { return color; }
public void setColor(String color) { this.color = color; } }
复制代码


public abstract class Chessman {		private Location l;		public Chessman(Location l) {		super();		this.l = l;	}		public Location getL() {		return l;	}
public void setL(Location l) { this.l = l; }
abstract public void put();
}
复制代码


public class WhiteChessman extends Chessman {		public WhiteChessman(Location l) {		super(l);		// TODO Auto-generated constructor stub	}
@Override public void put() { System.out.println("在("+super.getL().getX()+","+super.getL().getY()+")的位置放一个白子。"); }
}
复制代码


public class BlackChessman extends Chessman {
public BlackChessman(Location l) { super(l); // TODO Auto-generated constructor stub }
@Override public void put() { System.out.println("在("+super.getL().getX()+","+super.getL().getY()+")的位置放一个黑子。"); }
}
复制代码


public class ChessFactory {		private List<Chessman> l=new ArrayList<Chessman>();		public Chessman getChessman(Location t) {		Chessman c=null;		if(t.getColor().equals("black"))			c=new BlackChessman(t);		else			c=new WhiteChessman(t);		int f=0;		if(!l.isEmpty()) {			for(Chessman i:l) {				if(i.getL().equals(t)) {					f=1;				}			}			if(f==0)				l.add(c);		}else {			l.add(c);		}		return c;	}
public List<Chessman> getL() { return l; }
public int getNum() { return l.size(); }
}
复制代码


public class Client {
public static void main(String[] args) { ChessFactory cf=new ChessFactory(); Location l1=new Location(1,2,"black"); Chessman c1=cf.getChessman(l1); c1.put(); Location l2=new Location(1,2,"white"); Chessman c2=cf.getChessman(l2); c2.put();
}
}
复制代码

【UML】


用户头像

还未添加个人签名 2021.03.30 加入

还未添加个人简介

评论

发布
暂无评论
设计模式--享元模式