Объяснить шаблон фасада на примере C ++? - PullRequest
17 голосов
/ 30 октября 2008

Я проверил статью в википедии , и похоже, что в нем отсутствует версия кода на c ++. Я не могу полностью оценить шаблон Facade без этого, не могли бы вы помочь мне объяснить это с помощью C ++?

Ответы [ 6 ]

23 голосов
/ 30 октября 2008

Шаблон фасада: предоставляет унифицированный - упрощенный интерфейс для сложной подсистемы или набора интерфейсов. Он обеспечивает интерфейс более высокого уровня, одновременно отделяющий клиента от сложной подсистемы.

Пример, который поможет вам понять ... водитель такси. Вы говорите таксисту «Возьми меня в PointX» (унифицированный упрощенный высокоуровневый интерфейс), который затем начинает последовательность действий (поворачивает ключ, переключает передачи, нажимает акселератор и т. Д.) Для выполнения задачи. Он отвлекает внимание от сложности основных подсистем (коробка передач, двигатель и т. Д.), Чтобы вам не приходилось о них беспокоиться. Водитель также отделяет вас от фактического транспортного средства, используемого ... вы не взаимодействуете непосредственно с автомобилем. Вы могли бы потенциально дать ему Merc, но ваш интерфейс с драйвером все равно будет TakeMeTo (X) ... вы не привязаны к какой-либо конкретной модели / марке автомобиля.

В примере с реальным миром вы найдете фасады, где вы взаимодействуете со сторонними компонентами или библиотеками. Вы не хотите, чтобы ваш код зависел от конкретного поставщика, поэтому вы вводите интерфейс фасада для развязки. Также вы упростите этот интерфейс, например, ваш интерфейс фасада будет иметь метод с именем SendData (string), но внутренне реализация может вызвать n методов для m подпакетов в определенном порядке, чтобы выполнить задачу. Это то, что показывает диаграмма на странице википедии.

например. Перевод примера в C ++ и сохранение его крошечным

sResource = LWCPPSimple::get("http://www.perl.org")

Здесь вымышленная библиотека для WWW в C ++ - это фасад, объединяющий аспекты проблемы с протоколом, сетью и синтаксическим анализом, так что я могу сосредоточиться на своей основной задаче получения ресурса. Метод get скрывает / инкапсулирует / удерживает в одном месте сложность (и в некоторых случаях уродливость) HTTP, FTP и других разнообразных протоколов, запрос-ответ, управление соединением и т. Д. Также, если завтра создатели LWCPPSimple найдут способ сделать get () в два раза быстрее, я получаю преимущества производительности бесплатно. Код моего клиента не должен изменяться.

15 голосов
/ 30 октября 2008
class Engine
{

public:
    void Start() { }

};

class Headlights
{

public:
    void TurnOn() { }

};

//  That's your facade.
class Car
{

private:
    Engine engine;
    Headlights headlights;

public:
    void TurnIgnitionKeyOn()
    {
        headlights.TurnOn();
        engine.Start();
    }

};

int Main(int argc, char *argv[])
{
    //  Consuming facade.
    Car car;
    car.TurnIgnitionKeyOn();

    return 0;
}
4 голосов
/ 30 октября 2008

Я сделал поиск и замену на примере C #. Это может вам не помочь, потому что если вы понимаете C ++, вы должны понимать C #, поскольку он использует те же конструкции и ключевые слова (классы, функции, пространства имен, public и т. Д.)

// "Subsystem ClassA" 
#include <iostream>
class SubSystemOne
{
public:
    void MethodOne()
    {
        std::cout << " SubSystemOne Method" << std::endl;
    }
}

// Subsystem ClassB" 

class SubSystemTwo
{
public:
    void MethodTwo()
    {
        std::cout << " SubSystemTwo Method" << std::endl;
    }
}

// Subsystem ClassC" 

class SubSystemThree
{
public:
    void MethodThree()
    {
            std::cout << " SubSystemThree Method" << std::endl;
    }
}

// Subsystem ClassD" 

class SubSystemFour
{
public:
    void MethodFour()
    {
        std::cout << " SubSystemFour Method" << std::endl;
    }
}

// "Facade" 

class Facade
{
    SubSystemOne one;
    SubSystemTwo two;
    SubSystemThree three;
    SubSystemFour four;

public:
    Facade()
    {
    }

    void MethodA()
    {
        std::cout << "\nMethodA() ---- " << std::endl;
        one.MethodOne();
        two.MethodTwo();
        four.MethodFour();
    }
    void MethodB()
    {
        std::cout << "\nMethodB() ---- " << std::endl;
        two.MethodTwo();
        three.MethodThree();
    }
}

int Main()
{
    Facade facade = new Facade();

    facade.MethodA();
    facade.MethodB();

    return 0;
}
3 голосов
/ 30 октября 2008

В некотором смысле Facade - это просто API для клиентов, которые хотят взаимодействовать с чем-то скрытым.

Фасад полезен при представлении простого C API для чего-то, что реализовано в C ++ или просто более сложно, чем API. Или получить фиксированный барьер между клиентом и библиотекой, когда библиотеке необходимо пройти через многочисленные итеративные обновления и вы хотите как можно меньше воздействовать на клиента. Например, если библиотеку на основе C необходимо обновить внутренне до C ++ или чего-то еще, или просто заменить на что-то совершенно другое, то Facade - это хороший средний уровень для клиента.

2 голосов
/ 30 октября 2008

Есть C ++ примеры для Фасад на этом отличном сайте по шаблонам дизайна.

0 голосов
/ 16 марта 2010
class A {
    private B b; // Class A uses Class B, the "interface"
    public int f() { return b.g(); }
};

class B {
    private C c; // class B uses class C, a "subsystem"
    private ... ...; // other subsystems can be added
    public int g() { c.h(); return c.i(); }
};

class C { // a subsystem
    public void h() { ... }
    public int i() { return x; }
};

Класс A не будет напрямую использовать какие-либо методы или напрямую влиять на состояние класса C или любой другой подсистемы, содержащейся в классе B. Здесь показана только одна подсистема, потому что не имеет значения, сколько существует подсистем.

...