design_pattern_bridge

This post implements bridge pattern in <Head First Design Patterns>.  The bridge pattern decomposes the component's interface and implementation into orthogonalclass hierarchies. If there are changes in bother interface and implementation (two-dimention change), use bridge. If there is change only along one-dimention,

interface or implementation, inheritance will do the job.


The interface class contains a pointer to the abstract implementation class. This pointer is initialized with an instance of a concrete implementation class, but all subsequent interaction from the interface class to the implementation class is limited to the abstraction maintained in the implementation base class. The client interacts with the interface class, and it in turn "delegates" all requests to the implementation class.


The interface object is the "handle" known and used by the client;while the implementation object, or "body", is safely encapsulated to ensure that it may continue to evolve, or be entirely replaced (or shared at run-time. Use the Bridge pattern when:

  • you want run-time binding of the implementation,
  • you have a proliferation of classes resulting from a coupled interface and numerous implementations,
  • you want to share an implementation among multiple objects,
  • you need to map orthogonal class hierarchies.

Consequences include:

  • decoupling the object's interface,
  • improved extensibility (you can extend (i.e. subclass) the abstraction and implementation hierarchies independently),
  • hiding details from clients.
To use bridge pattern, we need to

  1. Decide if two orthogonal dimensions exist in the domain. These independent concepts could be: abstraction/platform, or domain/infrastructure, or front-end/back-end, or interface/implementation.
  2. Design the separation of concerns: what does the client want,and what do the platforms provide.
  3. Design a platform-oriented interface that is minimal, necessary,and sufficient. Its goal is to decouple the abstraction from the platform.
  4. Define a derived class of that interface for each platform.
  5. Create the abstraction base class that "has a" platform object and delegates the platform-oriented functionality to it.
  6. Define specializations of the abstraction class if desired.

TV class

class TV {
public:
    TV() {}
    virtual ~TV() {}
	virtual void on() = 0;
	virtual void off() = 0;
	virtual void tuneChannel(int channel) = 0;
};

class Sony : public TV {
private:
    std::string location;

public:
    Sony(const std::string& location_):location(location_) {}
	void on() {
		std::cout << "Sony " << location.c_str() << " TV is on" << std::endl;
	}
	void off() {
		std::cout << "Sony " << location.c_str() << " TV is off" << std::endl;
	}
	void tuneChannel(int channel) {
		std::cout << "Sony " << location.c_str() << " tuned to channel " << channel << std::endl;
	}
};

class RCA : public TV {
private:
    std::string location;

public:
    RCA(const std::string& location_):location(location_) {}
	void on() {
        std::cout << "RCA " << location.c_str() << " TV is on" << std::endl;
	}
	void off() {
		std::cout << "RCA " << location.c_str() << " TV is off" << std::endl;
	}
	void tuneChannel(int channel) {
		std::cout << "RCA " << location.c_str() << " tuned to channel " << channel << std::endl;
	}
};
Controller class

#include <./tv.hpp>

class RemoteControl {
private:
    RemoteControl( const RemoteControl& ); // Disable copy constructor
	void operator=( const RemoteControl& ); // Disable assignment operator
protected:
    TV* implementor;

public:
	RemoteControl():implementor(NULL) {}
	virtual ~RemoteControl() { delete implementor; }
	virtual void on() { implementor->on(); }
	virtual void off() { implementor->off(); }
    virtual void setChannel(int channel ) { implementor->tuneChannel(channel); }
};

class RCAControl : public RemoteControl {
private:
    int currentStation;

public:
    RCAControl(const std::string& location):currentStation(0){
        implementor = new RCA(location);
	}
	void setStation(int channel) {
		currentStation = channel;
		setChannel(currentStation);
	}
	void nextChannel() {
		currentStation++;
		setChannel(currentStation);
	}
	void previousChannel() {
		currentStation--;
		setChannel(currentStation);
	}
};

class SonyControl : public RemoteControl {
private:
    int currentStation;

public:
    SonyControl(const std::string& location ):currentStation(0) {
		implementor = new Sony( location );
	}
	void setStation(int channel) {
		currentStation = channel;
		setChannel(currentStation);
	}
	void nextChannel() {
		currentStation++;
		setChannel(currentStation);
	}
	void previousChannel() {
		currentStation--;
		setChannel(currentStation);
	}
};
The main function is

#include <iostream>
#include <memory>
#include <vector>
#include <./tv.hpp>
#include <./controller.hpp>

int main()
{
    std::vector<RemoteControl*> remotes;

	std::auto_ptr<SonyControl> sonyControl(new SonyControl( "XBR in living room" ));
	remotes.push_back(sonyControl.get());

	std::auto_ptr<RCAControl> rcaControl(new RCAControl("19 inch in kitchen" ));
	remotes.push_back(rcaControl.get());

	// turn on all tv's
	std::vector<RemoteControl*>::iterator iterator;
	for( iterator = remotes.begin(); iterator != remotes.end(); iterator++ ) {
		(*iterator )->on();
	}

	sonyControl->nextChannel();
	rcaControl->setStation(35);

	// turn off all tv's
	for( iterator = remotes.begin(); iterator != remotes.end(); iterator++ ) {
		( *iterator )->off();
	}

    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值