做网站建设的好处团购网站建设流程
做网站建设的好处,团购网站建设流程,四川建设厅报名网站,广州app网站开发动机
由于某些类型的固有的实现逻辑#xff0c;使得它们具有两个变化的维度#xff0c;乃至多个变化的维度。
如何应对这种“多维度的变化”#xff1f;如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化#xff0c;而不引入额外的复杂度 举个栗子
我们…动机
由于某些类型的固有的实现逻辑使得它们具有两个变化的维度乃至多个变化的维度。
如何应对这种“多维度的变化”如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化而不引入额外的复杂度 举个栗子
我们有一个发送消息的抽象基类
class Messager{
public:virtual void Login(string name, string password) 0;virtual void SendMessage(string message) 0;virtual void SendPicture(Image image) 0;virtual void PlaySound() 0;virtual void DrawShape() 0;virtual void WriteText() 0;virtual void Connect() 0;virtual ~Messager() {}
};
在这种业务场景下我们需要发送消息实现登录发送文字发送图片的功能。同时也可能有播放声音等等其他的功能需求。
针对不同的平台我们需要不同的实现逻辑来完成基础需求。
class PCMessagerBase : public Messager{
public:virtual void PlaySound(){//PC平台的实现逻辑}virtual void DrawShape(){//PC平台的实现}virtual void WriteText(){//PC平台的实现}virtual void Connect(){//PC平台的实现}
};class MobileMessagerBase : public Messager{
public:virtual void PlaySound(){//Mobile平台的实现逻辑}virtual void DrawShape(){//Mobile平台的实现}virtual void WriteText(){//Mobile平台的实现}virtual void Connect(){//Mobile平台的实现}
};
针对具体的不同业务场景我们需要有不同的逻辑。比如说我们需要一种精简版的逻辑同时需要一种完美版的逻辑类似针对非会员和会员的不同处理
//业务逻辑
class PCMessagerLite : public PCMessagerBase{
public:virtual void Login(string name, string password){PCMessagerBase::Connect(); //在登录前与服务器等等保持连接//...}virtual void SendMessage(string message){PCMessagerBase::WriteText(); //在发送消息前进行消息的输入//...}virtual void SendPicture(Image image){PCMessagerBase::DrawShape(); //发送图片前对图片的处理等等//...}
};class PCMessagerPerfect : public PCMessagerBase{
public:virtual void Login(string name, string password){PCMessagerBase::PlaySound();PCMessagerBase::Connect(); //在登录前与服务器等等保持连接//...}virtual void SendMessage(string message){PCMessagerBase::PlaySound();PCMessagerBase::WriteText(); //在发送消息前进行消息的输入//...}virtual void SendPicture(Image image){PCMessagerBase::PlaySound();PCMessagerBase::DrawShape(); //发送图片前对图片的处理等等//...}
};
perfect版本在lite版本的基础上可能有一些其他的行为比如说播放一段音乐等等。
//业务逻辑
class MobileMessagerLite : public MobileMessagerBase{
public:virtual void Login(string name, string password){MobileMessagerBase::Connect(); //在登录前与服务器等等保持连接//...}virtual void SendMessage(string message){MobileMessagerBase::WriteText(); //在发送消息前进行消息的输入//...}virtual void SendPicture(Image image){MobileMessagerBase::DrawShape(); //发送图片前对图片的处理等等//...}
};class MobileMessagerPerfect : public MobileMessagerBase{
public:virtual void Login(string name, string password){MobileMessagerBase::PlaySound();MobileMessagerBase::Connect(); //在登录前与服务器等等保持连接//...}virtual void SendMessage(string message){MobileMessagerBase::PlaySound();MobileMessagerBase::WriteText(); //在发送消息前进行消息的输入//...}virtual void SendPicture(Image image){MobileMessagerBase::PlaySound();MobileMessagerBase::DrawShape(); //发送图片前对图片的处理等等//...}
};
在移动端平台上也是一样的。业务流程是一样的可能有一些实现调用了MobileMessagerBase基类的方法。 存在的问题 现在存在的类的关系是这样的。这样的类中间存在的大量的重复代码比如PCMessageLite和MobileMessageLite的Login函数中逻辑明显是一样的唯一的区别在于调用的基类的Connect函数不同。
这样明显是一种不好的设计。这与我们之前写过的装饰模式中的问题非常类似。C设计模式 #5 装饰模式Decorator-CSDN博客 重构
如果参考装饰模式Decorator的方式我们可以将代码重构成以下这种形式。
class MessagerLite{Messager* messager; //在运行时 new PCMessagerBase() 或者 MobileMessagerBase()
public:virtual void Login(string name, string password) {messager-Connect(); //在登录前与服务器等等保持连接//...}virtual void SendMessage(string message) {messager-WriteText(); //在发送消息前进行消息的输入//...}virtual void SendPicture(Image image) {messager-DrawShape(); //发送图片前对图片的处理等等//...}
};class MessagerPerfect {Messager* messager; //在运行时 new PCMessagerBase() 或者 MobileMessagerBase()
public:virtual void Login(string name, string password) {messager-PlaySound();messager-Connect(); //在登录前与服务器等等保持连接//...}virtual void SendMessage(string message) {messager-PlaySound();messager-WriteText(); //在发送消息前进行消息的输入//...}virtual void SendPicture(Image image) {messager-PlaySound();messager-DrawShape(); //发送图片前对图片的处理等等//...}
};
看起来这种方法是可行的但是注意这种方法存在着致命的缺陷。
PCMessagerBase和MobileMessagerBase这两个类只重载了Messager类中的两个三个方法另外三个依然是纯虚函数。PCMessagerBase和MobileMessagerBase这两个类依然是纯虚基类它们是不可以被实例化的也就是说我们在运行时是无法初始化MessagerLite的messager指针为PCMessagerBase的。
造成这种问题的原因是Messager的这些函数放在一个类中并不合适。我们将代码彻底重构成如下形式
class Messager {
protected:MessagerImp* messager; //在运行时 new PCMessagerBase() 或者 MobileMessagerBase()
public:virtual void Login(string name, string password) 0;virtual void SendMessage(string message) 0;virtual void SendPicture(Image image) 0;virtual ~Messager() {}
};class MessagerImp {
public:virtual void PlaySound() 0;virtual void DrawShape() 0;virtual void WriteText() 0;virtual void Connect() 0;virtual ~MessagerImp() {}
};class PCMessagerBase : public MessagerImp {
public:virtual void PlaySound() {//PC平台的实现逻辑}virtual void DrawShape() {//PC平台的实现}virtual void WriteText() {//PC平台的实现}virtual void Connect() {//PC平台的实现}
};class MobileMessagerBase : public MessagerImp {
public:virtual void PlaySound() {//Mobile平台的实现逻辑}virtual void DrawShape() {//Mobile平台的实现}virtual void WriteText() {//Mobile平台的实现}virtual void Connect() {//Mobile平台的实现}
};//业务逻辑
class MessagerLite : public Messager{
public:virtual void Login(string name, string password) {messager-Connect(); //在登录前与服务器等等保持连接//...}virtual void SendMessage(string message) {messager-WriteText(); //在发送消息前进行消息的输入//...}virtual void SendPicture(Image image) {messager-DrawShape(); //发送图片前对图片的处理等等//...}
};class MessagerPerfect : public Messager{
public:virtual void Login(string name, string password) {messager-PlaySound();messager-Connect(); //在登录前与服务器等等保持连接//...}virtual void SendMessage(string message) {messager-PlaySound();messager-WriteText(); //在发送消息前进行消息的输入//...}virtual void SendPicture(Image image) {messager-PlaySound();messager-DrawShape(); //发送图片前对图片的处理等等//...}
}; 当前类的关系是这样的我们成功的将业务上的扩展MessagerLite/MessagerPerfect与平台上的扩展PCMessagerBase/MobileMessagerBase两个方向上分开。用(nm)数量的类实现了(n*m)的功能。 模式定义
将抽象部分业务功能与实现部分平台实现分离使它们都可以独立地变化。——《设计模式》GoF 同样红色的部分是稳定的蓝色的部分是变化的。
体现在我们上面的代码中就是Messager类与MessagerImp类中间搭了一座桥。使得业务功能与平台扩展两个方向上可以分开变化。 总结
桥模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系使得抽象和实现可以沿着各自的维度变化。所谓抽象和实现沿着各自维度变化即“子类化”桥模式有时候类似于多继承方案但是多继承方案往往违背单一职责原则即一个类只有一个变化的原因复用性较差。桥模式是比多继承方案更好的解决办法。桥模式一般应用于“两个非常强的变化维度”有时一个类有多于两个的维度变化这时也可以使用桥模式的扩展模式。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/92664.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!