Строитель (Builder)

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск

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

Назначение

Предоставляет интерфейс для создания частей сложного объекта и возвращения сконструированного объекта.

Описание

В некоторых задачах требуется создавать сложные объекты с большим количеством подобъектов, имеющих между собой сложные связи. В подобных случаях имеет смысл определить отдельный класс Builder, на который возлагается ответственность за создание составных объектов и координацию взаимодействия их частей.

Реализация

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

BuilderCommon.png

Участники

  • Builder - строитель

Задает интерфейс для создания частей объекта Product

  • ConcreteBuilder - конкретный строитель

Конструирует и собирает вместе части продукта посредством реализации интерфейса Builder

Предоставляет интерфейс для доступа к продукту

  • Director - распорядитель

Конструирует объект, пользуясь интерфейсом Builder

  • Product - продукт

Представляет составной конструируемый объект

Код

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();
        }
    }
}

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

  • Позволяет изменять внутреннее представление продукта, определив подвид Builderа
  • Для объектов, требующих поэтапного создания, шаблон Builder играет роль объекта более высокого уровня, который управляет всем ходом процесса.
  • Недостаток: жесткая связь между Builder, его продуктом и частями этого продукта. Изменения, вносимые в продукт, требуют внесения изменений в Builder и в части продуукта.

Варианты

  • Определение у Builderа нескольких методов создания продукта