1

根据维基https://en.wikipedia.org/wiki/Decorator_pattern#Usage

装饰器可以在运行时添加或更改接口的行为。或者,当包装器必须尊重特定接口并且必须支持多态行为时,可以使用适配器,当需要与底层对象的更简单或更简单的接口时,可以使用 Facade。

我不明白polymorphic behavior。Adaptor哪里发生了多态,不就是adapter只是将一个接口转换成另一个接口吗?

4

2 回答 2

3

适配器不只是将一个接口转换为另一个接口吗?

是的。

Adaptor 中哪里发生了多态...?

假设您有两个类,它们做的事情大致相似,但具有不同的接口。您可以用适配器包装一个,使其接口与另一个接口匹配(或将它们都提供给某个共享 API 的适配器),然后相同的客户端代码可以多态地使用其中一个。

例如,两个相似的类:

struct Car {
    bool start();
    bool accelerate_gently_to(double kph);
};

struct Bicycle {
    bool start();
    bool set_gear(int);
    bool peddle(double rpm);
};

一个适配器,因此Bicycle可以使用与另一个相同的接口来控制一个(任意的):

struct Bicycle_Adapter_to_Accelerate_API {
    Bicycle b_;  // member, base, by-pointer - whatever
    bool start() { return b_.start(); }
    bool accelerate_gently_to(double kph) {
        int gear = calculate_best_gear_for_speed(kph);
        if (!b_.set_gear(gear)) return false;
        double rpm = calculate_rpm(kph, wheel_circumference, gear); 
        return b_.peddle(rpm);
    }
};

这允许以多态方式处理它们的客户端代码:

template <typename T>
void control_transport(T& t) {
    t.start();
    t.accelerate_gently_to(20);
    sleep(60);
    t.accelerate_gently_to(25);
}

假设您想使用运行时多态性(即虚拟分派)而不是编译时多态性:您将使用Carand 从基类派生 and 适配器virtual bool start();,或者为and 两个适配器从这样的基类派生virtual bool accelerate_gently_to(double kph);创建第二个适配器,Car然后您可以从非模板代码中进行多态调度:

void control_transport(Transport_Base_Class& t) {
    t.start();
    t.accelerate_gently_to(20);
    sleep(60);
    t.accelerate_gently_to(25);
}
于 2018-08-12T08:22:01.977 回答
0

它只是意味着可以将包装器传递给客户端,并且客户端必须与包装器很好地配合使用,而无需知道包装器的具体类型。客户端只需要知道包装器实现的接口。

我认为wiki文章的作者在这里有点冗长。

于 2018-08-12T06:14:22.320 回答