Как построить последовательность в вызовах методов беглого интерфейса - PullRequest
0 голосов
/ 24 февраля 2011

Привет, я хотел бы создать свободный интерфейс для создания объекта, своего рода фабрики или строителя.

Я понимаю, что мне нужно "вернуть это", чтобы методы стали цепными.

public class CarBuilder
{

   public  CarBuilder()
   {
       car = new Car();
   }
    private Car car;

    public CarBuilder AddEngine(IEngineBuilder engine)
    {
        car.Engine = engine.Engine();
        return this;
    }

    public CarBuilder AddWheels(IWheelsBuilder wheels)
    {
        car.Wheels = wheels.Wheels();
        return this;
    }
    public CarBuilder AddFrame(IFrameBuilder frame)
    {
        car.Frame = frame.Frame();
        return this;
    }

    public Car BuildCar()
    {
        return car;
    }

}

с этим я мог бы построить такую ​​машину:

 Car c = builder.AddFrame(fBuilder).AddWheels(wBuilder).AddEngine(eBuilder).BuildCar();

Но мне нужна специальная последовательность или рабочий процесс: Я могу строить колеса только на верхней части рамы, и когда колеса будут существовать, я смогу собрать двигатель. Таким образом, вместо того, чтобы предлагать каждый метод автомобилестроителя, я хочу иметь возможность добавить только рамку для строителя, а затем только колеса к раме и затем двигатель поверх этого ...

И как это будет или что будет хорошей реализацией, если у самого EngineBuilder есть свободный API, например, eBuilder.Cylinders (12) .WithPistons () ....

Было бы возможно иметь что-то подобное

Car c = builder.AddFrame(fBuilder).AddWheels(wBuilder).AddEngine(x=>x.WithCylinders(12).WithPistons()).BuildCar();

Итак, в общем, как структурировать поток свободного интерфейса и как вкладывать свободные интерфейсы?

Ответы [ 2 ]

0 голосов
/ 15 ноября 2017

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

Учитывая ваш пример, CarBuilder будет предлагать только AddFrame. Вместо возврата this, AddFrame возвращает объект класса CarBuilderWithFrame, который предлагает только AddWheels, который возвращает объект класса CarBuilderWithFrameAndWheels, который предлагает только AddEngine, который возвращает объект класса CarBuilderWithEverything который предлагает только Build.

Этот пример очень последовательный, и вы можете поспорить, имеет ли смысл проделать такую ​​большую работу для такого линейного процесса.

Пример, который мне нравится, касается печати. Объект Printer может вернуть объект PrintJob, который предлагает три метода: Cancel, Print или StartPage. Метод StartPage возвращает объект Page, который предоставляет вам методы для всех команд рисования, одна из которых называется EndPage и возвращает объект PrintJob. Это позволяет легко напечатать простое задание на печать.

Printer.StartPrintJob().StartPage().DrawText("Title").DrawIcon("logo.png").EndPage().Print();
0 голосов
/ 24 февраля 2011

Разве AddWheels не будет методом, относящимся к Frame?Вы также можете рассмотреть возможность исключения при запросе недопустимой операции, такой как добавление колес без рамки.

...