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