C#: Прототип

Prototype Прототип Prototype

Прототип — це породжуючий патерн, який дозволяє копіювати об'єкти будь-якої складності без прив'язки до їхніх конкретних класів.

Усі класи-Прототипи мають спільний інтерфейс. Тому ви можете копіювати об'єкти, не звертаючи уваги на їхні конкретні типи та бути завжди впевненими в тому, що отримаєте точну копію. Клонування здійснюється самим об'єктом-прототипу, що дозволяє йому скопіювати значення всіх полів, навіть приватних.

Детальніше про Прототип

Особливості паттерна на C#

Складність:

Популярність:

Застосування: Патерн Прототип реалізовано в базовій бібліотеці C# за допомогою інтерфейсу Cloneable.

Ознаки застосування патерну: Прототип легко визначається в коді за наявності методів clone(), copy() та інших.

Приклад: Структура патерну

Цей приклад показує структуру патерну Прототип, а саме — з яких класів він складається, які ролі ці класи виконують і як вони взаємодіють один з одним.

Program.cs: Приклад структури патерну

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RefactoringGuru.DesignPatterns.Prototype.Structural
{
    class Program
    {
        static void Main(string[] args)
        {
            Client client = new Client();
            client.ClientCode();
        }
    }

    class Client
    {
        public void ClientCode()
        {
            Prototype prototype = new Prototype();
            prototype.Primitive = 245;
            prototype.Component = new DateTime();
            prototype.CircularReference = new ComponentWithBackReference(prototype);

            Prototype prototype2 = prototype.Clone();
            if(prototype.Primitive == prototype2.Primitive)
            {
                Console.Write("Primitive field values have been carried over to a clone. Yay!\n");
            }
            else
            {
                Console.Write("Primitive field values have not been copied. Booo!\n");
            }

            if (prototype.Component == prototype2.Component)
            {
                Console.Write("Simple component has been cloned. Yay!\n");
            }
            else
            {
                Console.Write("Simple component has not been cloned. Booo!\n");
            }

            if (prototype.CircularReference == prototype2.CircularReference)
            {
                Console.Write("Component with back reference has been cloned. Yay!\n");
            }
            else
            {
                Console.Write("Component with back reference has not been cloned. Booo!\n");
            }

            if (prototype.CircularReference.Prototype == prototype2.CircularReference.Prototype)
            {
                Console.Write("Component with back reference is linked to the clone. Yay!\n");
            }
            else
            {
                Console.Write("Component with back reference is linked to original object. Booo!\n");
            }
        }
    }

    public class Prototype
    {
        public int Primitive { get; set; }

        public DateTime Component { get; set; }

        public ComponentWithBackReference CircularReference { get; set; }

        public Prototype()
        { }
        
        public Prototype Clone()
        {
            return CircularReference.Prototype;
        }
    }

    public class ComponentWithBackReference
    {
        public Prototype Prototype { get; set; }

        public ComponentWithBackReference(Prototype p)
        {
            Prototype = p;
        }
    }
}

Output.txt: Результат виконання

Primitive field values have been carried over to a clone. Yay!
Simple component has been cloned. Yay!
Component with back reference has been cloned. Yay!
Component with back reference is linked to the clone. Yay!