目录
享元模式
引言
定义
模式类图
实例
实例描述
实例类图
实现代码
模式扩展
单纯享元模式
复合享元模式
总结
模式优点
模式缺点
当系统中存在大量相同或相似的对象时,享元模式是一种较好的解决方案,它通过共享技术实现相同或相似的细粒度对象的复用,从而节约了内存空间。
英文定义:"Use the sharing to support the large numbers of fine-grained objects efficiently."。
中文定义:运用共享技术有效的支持大量细粒度对象的复用。
享元模式重要等级★☆☆☆☆ 享元模式难度等级★★★★☆
享元模式包含如下角色:
1.Flyweight (抽象享元类)
2.ConcreteFlyweight(具体享元类)
3.UnsharedConcreteFlyweight(非共享具体享元类):并非所有的子类都能共享,不能被共享的则直接实例化,而不通过享元工厂生成。
4.FlyweightFactory(享元工厂):享元工厂针对抽象享元类编程,维护一个享元池。通常使用KV集合存储。
很多网络设备是支持共享的,如交换机,集线器等,多台计算机终端可以连接同一个网络设备,但是必须使用不同的网络设备的端口(Port),将端口从网络设备中提取出来作为外部状态,用享元模式设计该情景。
1)端口类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class Port
{
private string ip;
private static int autoIP = 1;
public Port()
{
this.ip = "100" + autoIP++;
}
public Port(string ip)
{
this.ip = ip;
}
public string Ip
{
get
{
return ip;
}
}
}
2)抽象网络设备类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
abstract class NetWorkDevice
{
protected string type;
protected NetWorkDevice(string type)
{
this.type = type;
}
public abstract void Use(Port port);
}
3)交换机类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class Switch : NetWorkDevice
{
public Switch(string type)
:base(type)
{
}
public override void Use(Port port)
{
Console.WriteLine("Linked by switch,type is {0},Port is {1}.", type, port.Ip);
}
}
4)集线器类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class Hub : NetWorkDevice
{
public Hub(string type)
:base(type)
{
}
public override void Use(Port port)
{
Console.WriteLine("Linked by hub,type is {0},Port is {1}.", type, port.Ip);
}
}
5)网络设备工厂类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class DeviceFactory
{
private Dictionary devices = new Dictionary()
{
{ "CISCO",new Hub("Cisco - WS - C2950 - 24") },
{ "TP",new Hub("TP - LINK - HF8M") },
};
private int totalTerminal;
public int TotalTerminal
{
get
{
return totalTerminal;
}
}
public NetWorkDevice GetNetWorkDevice(string type)
{
totalTerminal++;
return devices[type.ToUpper()];
}
public int TotalDevice
{
get { return devices.Count; }
}
}
6)测试代码
using System.Text;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
NetWorkDevice n1, n2, n3, n4, n5;
DeviceFactory deviceFactory = new DeviceFactory();
n1 = deviceFactory.GetNetWorkDevice("cisco");
n2 = deviceFactory.GetNetWorkDevice("cisco");
n3 = deviceFactory.GetNetWorkDevice("cisco");
n4 = deviceFactory.GetNetWorkDevice("tp");
n5 = deviceFactory.GetNetWorkDevice("tp");
n1.Use(new Port());
n2.Use(new Port());
n3.Use(new Port("1022"));
n4.Use(new Port("1024"));
n5.Use(new Port());
Console.WriteLine(string.Format("Total Device:{0} \nTotal Terminal:{1}", deviceFactory.TotalDevice ,deviceFactory.TotalTerminal));
Console.ReadKey();
}
}
7)运行结果
在单纯享元模式中,所有的享元对象都是可以共享的,即所有的抽象享元类的子类都可以共享,不存在非共享具体享元类。单纯享元模式的结构如下图所示。(即没有非共享子类)
将一些单纯享元使用组合模式加以组合,可以形成复合享元对象,这样的复合享元对象本身不能共享,但是它们可以分解城单纯享元对象。通过复合享元对象,可以确保复合享元类中所包含的每个单纯享元类都具有相同的外部状态,而这些单纯享元的内部状态往往可以不同。复合享元模式结构如下图所示。
1)享元模式可以极大的减少内存中对象的数量,使得相同的对象或者相似的对象在内存中是保存一份。
2)享元模式的外部状态相对独立,而且不会影响到内部状态,从而使得享元对象可以在不同的环境中被共享。
1)分离出内部状态和外部状态有时候是比较困难的,程序的逻辑可能较复杂。