概述
- 享元模式是以共享的方式高效地支持大量的细粒度对象。
- 享元对象能做到共享的关键是==区分内部状态和外部状态==。内部状态是存储在享元对象内部并且不会随环境改变而改变。因此内部状态可以共享。
享元模式结构图
示意性代码
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】
评论