FlyweightPattern-享元模式
在C#中,享元模式(Flyweight Pattern)是一种结构型设计模式,它旨在通过共享对象来最大程度地减少内存使用和提高性能。享元模式适用于需要创建大量相似对象的情况,通过共享相同数据的方式来减少对象的数量。
享元模式有以下几个关键角色:
Flyweight(享元):定义共享对象的接口,通常包含公共状态的操作方法。享元对象在内部不存储具体的状态,而是依赖外部传入的状态。
ConcreteFlyweight(具体享元):实现享元接口,并为内部状态添加具体实现。具体享元对象可以被共享。
FlyweightFactory(享元工厂):负责创建和管理享元对象。它维护一个享元池,用于存储已经创建的享元对象,以便在需要时进行共享。
下面是一个示例,展示如何使用享元模式在C#中实现一个简单的字体管理器:
namespace FlyweightPattern_享元模式
{
internal class Program
{
// Flyweight
public interface IFont
{
void SetFont(string fontName, int size);
void Render(string text);
}
// ConcreteFlyweight
public class Font : IFont
{
private string fontName;
private int size;
public void SetFont(string fontName, int size)
{
this.fontName = fontName;
this.size = size;
}
public void Render(string text)
{
Console.WriteLine("Rendering text: " + text + " with font " + fontName + " and size " + size);
}
}
// FlyweightFactory
public class FontManager
{
private Dictionary<string, IFont> fonts = new Dictionary<string, IFont>();
private readonly static object FlyweightFactoryLock = new object();
public IFont GetFont(string key)
{
if (!fonts.ContainsKey(key))
//是为了优化性能,避免对象已经被初始化后,再次请求还需要等待锁
{
lock (FlyweightFactoryLock)//Monitor.Enter,保证方法体只有一个线程可以进入
{
if (!fonts.ContainsKey(key))
{
fonts.Add(key, new Font());
}
}
}
return fonts[key];
}
}
static void Main(string[] args)
{
FontManager fontManager = new FontManager();
// 获取并使用字体对象
IFont font1 = fontManager.GetFont("Arial");
font1.SetFont("Arial", 12);
font1.Render("Hello, world!");
// 再次获取字体对象
IFont font2 = fontManager.GetFont("Arial");
font2.Render("Flyweight pattern");
// 验证字体对象是否相同
Console.WriteLine(object.ReferenceEquals(font1, font2)); // 输出:True
Console.Read();
}
}
}
在上述示例中,使用享元模式实现了一个字体管理器。IFont是享元接口,定义了设置字体和渲染文本的方法。Font是具体享元对象,实现了享元接口,并保存了具体的字体名称和大小。FontManager是享元工厂,负责创建和管理享元对象。它在内部维护了一个字典,用于存储已经创建的享元对象。当客户端请求一个字体时,如果字体已经存在于字典中,则直接返回现有的享元对象;否则,创建一个新的享元对象并将其存储在字典中。
通过使用享元模式,可以在需要大量相似对象时节省大量内存,并提高性能。具体享元对象可以被多个客户端共享,避免了重复创建相同的对象。而享元工厂负责创建和管理享元对象,确保同一个对象只会被创建一次。