Прототип (Prototype)

Материал из Вики ИТ мехмата ЮФУ
Версия от 23:05, 29 августа 2014; Admin (обсуждение | вклад) (Диаграмма классов)

Перейти к: навигация, поиск

К основной странице курса

Назначение

Задаёт виды создаваемых объектов с помощью экземпляра-прототипа и создаёт новые объекты путём копирования этого прототипа.

Описание

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

Использование

Паттерн Прототип используется когда:

  • Инстанцируемые классы определяются во время выполнения
  • Для того чтобы избежать построение иерархий классов-фабрик, параллельных иерархии классов-продуктов

Реализация

Диаграмма классов

PrototypeCommon.png

Участники

Код

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

namespace MazeGameBuilder
{
    interface MazeBuilder 
    {
        void BuildMaze();
        void BuildRoom(int n);
        void BuildDoor(int roomFrom, int roomTo);
	Maze GetMaze();
    };

    class MazeGame
    {
        public Maze CreateMaze(MazeBuilder builder) 
        {
            builder.BuildMaze();

            builder.BuildRoom(1);
            builder.BuildRoom(2);
            builder.BuildDoor(1, 2);

            return builder.GetMaze();
        }
    }

    class StandardMazeBuilder: MazeBuilder 
    {
        private Maze maze;
        public virtual void BuildMaze() 
	{ 
            maze = new Maze(); 
        }
	public virtual void BuildRoom(int n) 
        {
	    if (maze.RoomNo(n) == null) 
            {
		Room r = new Room(n);
		maze.AddRoom(r);
		r.SetSide(Direction.North, new Wall());
                r.SetSide(Direction.South, new Wall());
                r.SetSide(Direction.East, new Wall());
                r.SetSide(Direction.West, new Wall());
	    }
	}
	public virtual void BuildDoor(int n1, int n2) 
        {
	    Room r1 = maze.RoomNo(n1);
	    Room r2 = maze.RoomNo(n2);
	    Door d = new Door(r1,r2);
	    r1.SetSide(CommonWall(r1,r2),d);
	    r2.SetSide(CommonWall(r2,r1),d);
	}

        public virtual Maze GetMaze() 
	{ 
            return maze;
        }

        private Direction CommonWall(Room r1, Room r2)
        {
            // Информация должна храниться глобально
            // Здесь - самый простой вариант для двух комнат
            if (r1.RoomNumber == 1 && r2.RoomNumber == 2)
                return Direction.East;
            return Direction.West;
        }
    }



    class ProgramBuilder
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Builder");
            MazeGame game = new MazeGame();
            StandardMazeBuilder b = new StandardMazeBuilder();
            game.CreateMaze(b);
            Maze maze = b.GetMaze();
        }
    }
}

Достоинства и недостатки

Варианты