1. 程式人生 > >設計模式系列 - 原型模式

設計模式系列 - 原型模式

ret gets 通過 var 重復 args eid 具體類 default

所謂原型模式是指為創建重復對象提供一種新的可能。

介紹

當面對系統資源緊缺的情況下,如果我們在重新創建一個新的完全一樣的對象從某種意義上來講是資源的浪費,因為在新對象的創建過程中,是會有系統資源的消耗,而為了盡可能的節省系統資源,我們有必要尋找一種新的方式來創建重復對象。

類圖描述

技術分享圖片

由於Shape 抽象類繼承了 ICloneable 接口,所以通過上圖我們可以發現,所有具體的類型都繼承 Shape 抽象類,並實現 Clone() 方法即可。

代碼實現

1、定義具有抽象基類

public abstract class Shape : ICloneable
{
    private string id;
    protected string type;
    public abstract void Draw();

    public string GetId() => id;
    public string GetType() => type;

    public void SetId(string id) => this.id = id;

    public new object MemberwiseClone() => base.MemberwiseClone();
    public abstract object Clone();
}

2、定義具體類型

public class Circle:Shape
{
    public Circle() => type = "Circle";
    public override void Draw()
    {
        Console.WriteLine("I am a Circle");
    }
    public override object Clone()
    {
        Circle obj = new Circle();
        obj.type = type;
        obj.SetId(this.GetId());
        return obj;
    }
}

public class Rectangle:Shape
{
    public Rectangle() => type = "Rectangle";
    public override void Draw()
    {

        Console.WriteLine("I am a Rectangle");
    }
    public override object Clone()
    {
        Rectangle obj = new Rectangle();
        obj.type = type;
        obj.SetId(this.GetId());
        return obj;

    }
}

public class Square:Shape
{
    public Square() => type = "Square";
    public override void Draw()
    {
        Console.WriteLine("I am a Square");
    }
    public override object Clone()
    {
        Square obj = new Square();
        obj.type = type;
        obj.SetId(this.GetId());
        return obj;
    }
}

3、創建種子數據

public class ShapeCache
{
    private  static  HashSet<Shape> shapeMap = new HashSet<Shape>();

    public static Shape GetShape(string shapeId)
    {
        var cachedShape = shapeMap.FirstOrDefault(p => p.GetId() == shapeId);
        return (Shape) cachedShape?.Clone();
    }

    public static void LoadCache()
    {
        Circle circle = new Circle();
        circle.SetId("1");
        shapeMap.Add(circle);


        Square square = new Square();
        square.SetId("2");
        shapeMap.Add(square);

        Rectangle rectangle = new Rectangle();
        rectangle.SetId("3");
        shapeMap.Add(rectangle);
    }
}

4、上層調用

class Program
{
    static void Main(string[] args)
    {
        ShapeCache.LoadCache();

        Shape clonedShape1 = (Shape) ShapeCache.GetShape("1");
        Console.WriteLine(clonedShape1.GetType());
        clonedShape1.Draw();

        Shape clonedShape2 = (Shape)ShapeCache.GetShape("2");
        Console.WriteLine(clonedShape2.GetType());
        clonedShape2.Draw();

        Shape clonedShape3 = (Shape)ShapeCache.GetShape("3");
        Console.WriteLine(clonedShape3.GetType());
        clonedShape3.Draw();

        Console.ReadKey();
    }
}

總結

C# 中實現原型模式的關鍵是需要定義一個繼承 ICloneable 接口的抽象類,並在子類中重寫相應的 Clone() 方法即可。

設計模式系列 - 原型模式