设计模式之 享元模式 C# 范例

享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享对象来减少内存使用,尤其是在有大量相似对象的情况下。享元模式的关键思想是将对象的内部状态和外部状态分开,将共享部分(内部状态)存储在享元对象中,而将不共享部分(外部状态)保存在客户端或使用时传递给享元对象。

享元模式的核心:

  • 共享享元对象:享元对象的内部状态是共享的,可以在多个上下文中复用。
  • 外部状态:外部状态通常是不同的,可以在每次使用时提供,而不是存储在享元对象中。
  • 享元工厂:享元工厂负责管理享元对象的创建和共享。如果已经存在相同的享元对象,工厂会直接返回该对象。

示例:图形对象管理系统

假设我们在绘制一个图形应用中,想要管理不同颜色和形状的图形对象。如果每个图形对象都独立存储颜色和形状的属性,内存消耗将会非常大,尤其是当图形数量很大时。我们可以使用享元模式来优化这个问题,通过共享相同的形状和颜色对象来减少内存的使用。

代码实现:

1. 定义享元对象接口
// 享元接口
public interface IShape
{
    void Draw(string color);  // 外部状态:颜色
}

2. 创建具体的享元对象
// 具体享元对象:圆形
public class Circle : IShape
{
    private readonly string _shape;  // 内部状态:形状,圆形不变

    public Circle()
    {
        _shape = "Circle";
    }

    public void Draw(string color)
    {
        Console.WriteLine($"Drawing a {_shape} with color {color}");
    }
}

// 具体享元对象:矩形
public class Rectangle : IShape
{
    private readonly string _shape;  // 内部状态:形状,矩形不变

    public Rectangle()
    {
        _shape = "Rectangle";
    }

    public void Draw(string color)
    {
        Console.WriteLine($"Drawing a {_shape} with color {color}");
    }
}

3. 享元工厂类
 
// 享元工厂类,用于管理享元对象
public class ShapeFactory
{
    private readonly Dictionary<string, IShape> _shapes = new Dictionary<string, IShape>();

    public IShape GetShape(string shapeType)
    {
        if (!_shapes.ContainsKey(shapeType))
        {
            IShape shape = shapeType switch
            {
                "Circle" => new Circle(),
                "Rectangle" => new Rectangle(),
                _ => throw new ArgumentException("Shape type not supported")
            };
            _shapes[shapeType] = shape;
        }

        return _shapes[shapeType];
    }
}

4. 客户端代码
 
csharp
class Program
{
    static void Main()
    {
        var shapeFactory = new ShapeFactory();

        // 获取并使用共享的享元对象
        IShape circle1 = shapeFactory.GetShape("Circle");
        circle1.Draw("Red");

        IShape rectangle1 = shapeFactory.GetShape("Rectangle");
        rectangle1.Draw("Blue");

        // 重复使用共享的享元对象
        IShape circle2 = shapeFactory.GetShape("Circle");
        circle2.Draw("Green");

        IShape rectangle2 = shapeFactory.GetShape("Rectangle");
        rectangle2.Draw("Yellow");

        // 可以看到 "Circle" 和 "Rectangle" 被共享
    }
}

输出结果:

 
Drawing a Circle with color Red
Drawing a Rectangle with color Blue
Drawing a Circle with color Green
Drawing a Rectangle with color Yellow

享元模式的优点:

  1. 节省内存:通过共享相同的对象实例,享元模式可以显著减少对象的创建,从而节省内存。
  2. 提高性能:对象共享能够减少内存消耗,特别是在系统中有大量相似对象的情况下。
  3. 简化对象管理:享元工厂可以统一管理共享的对象,避免了大量重复创建对象的复杂性。

享元模式的缺点:

  1. 增加复杂性:实现享元模式可能会增加代码的复杂性,因为需要维护享元工厂和享元对象的生命周期。
  2. 共享的对象不可变:享元对象的内部状态必须是不可变的,否则会影响其他共享同一对象的客户端。
  3. 外部状态的传递:享元对象只存储共享的内部状态,外部状态需要在调用时传递,因此可能增加了调用的复杂度。

适用场景:

  • 内存管理:当系统中有大量的对象,并且它们的状态(属性)大多数是相同的,使用享元模式可以减少内存消耗。
  • 对象共享:当多个客户端需要使用相同类型的对象时,享元模式可以帮助共享这些对象。
  • 复杂系统的优化:在图形绘制、文字处理、数据缓存等场景中,享元模式能有效提高系统性能。

总结:

享元模式通过共享内存和减少对象创建次数来优化内存和性能,尤其适用于大量相似对象的场景。通过享元工厂来管理共享的享元对象,客户端可以通过传递外部状态来使用这些共享对象,从而达到节省内存和提高性能的目的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值