好了,现在看到的这段代码可以说是很好地符合了面向对象的思想,但是同时我们也为此付出了沉重的代价,那就是性能上的开销,可以想象,在一篇文档中,字符的数量远不止几百个这么简单,可能上千上万,内存中就同时存在了上千上万个Charactor对象,这样的内存开销是可想而知的。进一步分析可以发现,虽然我们需要的Charactor实例非常多,这些实例之间只不过是状态不同而已,也就是说这些实例的状态数量是很少的。所以我们并不需要这么多的独立的Charactor实例,而只需要为每一种Charactor状态创建一个实例,让整个字符处理软件共享这些实例就可以了。看这样一幅示意图:
现在我们看到的A,B,C三个字符是共享的,也就是说如果文档中任何地方需要这三个字符,只需要使用共享的这三个实例就可以了。然而我们发现单纯的这样共享也是有问题的。虽然文档中的用到了很多的A字符,虽然字符的symbol等是相同的,它可以共享;但是它们的pointSize却是不相同的,即字符在文档中中的大小是不相同的,这个状态不可以共享。为解决这个问题,首先我们将不可共享的状态从类里面剔除出去,即去掉pointSize这个状态(只是暂时的J),类结构图如下所示
图5
示意性实现代码:
// "Charactor" public abstract class Charactor { //Fields protected char _symbol; protected int _width; protected int _height; protected int _ascent; protected int _descent; //Method public abstract void Display(); } // "CharactorA" public class CharactorA : Charactor { // Constructor public CharactorA() { this._symbol = 'A'; this._height = 100; this._width = 120; this._ascent = 70; this._descent = 0; } //Method public override void Display() { Console.WriteLine(this._symbol); } } // "CharactorB" public class CharactorB : Charactor { // Constructor public CharactorB() { this._symbol = 'B'; this._height = 100; this._width = 140; this._ascent = 72; this._descent = 0; } //Method public override void Display() { Console.WriteLine(this._symbol); } } // "CharactorC" public class CharactorC : Charactor { // Constructor public CharactorC() { this._symbol = 'C'; this._height = 100; this._width = 160; this._ascent = 74; this._descent = 0; } //Method public override void Display() { Console.WriteLine(this._symbol); } }