“单一职责”模式:
在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同事充斥着重复代码,这时候的关键是划分责任。
动机
由于某些类型的固有的实现逻辑,使得它们具有两个纬度的变化,乃至多个纬度的变化。
如何应对这种"多维度的变化"?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?
处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联。
使用组合代替继承,在第一个变化维度中包含第二个维度的指针,这个指针就是桥bridge。
通过下面实例说明桥模式的实现机制:
#include <iostream>
#include <memory>
using namespace std;
class MessagerImpl;
// 第一个变化纬度:业务抽象不同,完整版和简版对于一些功能的实现不同
class Messager {
public:
virtual void login() = 0;
virtual void send_message() = 0;
virtual void send_picture() = 0;
Messager(unique_ptr<MessagerImpl> m) : messager_impl(std::move(m)) {}
virtual ~Messager() {}
protected:
unique_ptr<MessagerImpl> messager_impl; // bridge
};
// 第二个变化纬度:平台实现不同,pc和mobile对一些功能的实现不同
class MessagerImpl {
public:
virtual void play_sound() = 0;
virtual void draw_shape() = 0;
virtual void write_text() = 0;
virtual void connect() = 0;
virtual ~MessagerImpl() { std::cout << "virtual ~MessagerImpl() {}" << std::endl; }
};
// 简版的实现
class MessagerLite : public Messager {
public:
virtual void login() override {
messager_impl->connect();
}
virtual void send_message() override {
messager_impl->write_text();
}
virtual void send_picture() override {
messager_impl->draw_shape();
}
MessagerLite(unique_ptr<MessagerImpl> m) : Messager(std::move(m)) {}
};
// 完整版的实现,这里体现为多加了play_sound的操作
class MessagerPerfect : public Messager {
public:
virtual void login() override {
messager_impl->play_sound();
messager_impl->connect();
}
virtual void send_message() override {
messager_impl->play_sound();
messager_impl->write_text();
}
virtual void send_picture() override {
messager_impl->play_sound();
messager_impl->draw_shape();
}
MessagerPerfect(unique_ptr<MessagerImpl> m) : Messager(std::move(m)) {}
};
// pc端的实现
class PcMessagerImpl : public MessagerImpl {
public:
virtual void play_sound() override {
cout << "pc play_sound" << endl;
}
virtual void draw_shape() override {
cout << "pc draw_shape" << endl;
}
virtual void write_text() override {
cout << "pc write_text" << endl;
}
virtual void connect() override {
cout << "pc connect" << endl;
}
virtual ~PcMessagerImpl() { std::cout << "~PcMessagerImpl()"<<std::endl; }
};
// 移动端的实现
class MobileMessagerImpl : public MessagerImpl {
public:
virtual void play_sound() override {
cout << "mobile play_sound" << endl;
}
virtual void draw_shape() override {
cout << "mobile draw_shape" << endl;
}
virtual void write_text() override {
cout << "mobile write_text" << endl;
}
virtual void connect() override {
cout << "mobile connect" << endl;
}
};
int main() {
// 可以用m+n个类 实现 mxn个功能
unique_ptr<MessagerImpl> message_impl(new PcMessagerImpl);
unique_ptr<Messager> message(new MessagerPerfect(std::move(message_impl)));
message->login();
message->send_message();
message->send_picture();
return 0;
}
再举个例子来看,比如画笔有类型不同,颜色不同;那么类型中也有可能新增,颜色也有可能新增,如何设计这个情况