C++中public继承反思

在读11.6.5 iostream在设计方面的缺点章节时,作者陈硕提到了iostream在面向对象方面的设计缺陷:面向对象的public继承未满足继承非为复用,乃为被复用的Liskov替换原则。

书中提到iostream的继承体系多次违反了Liskov替换原则,这些地方的继承是为了复用基类的代码,而Liskov原则提到:继承并不是为了复用代码。由此我想到我可能在最近的项目中做了一些XB事情。


在最近的项目中,后台程序开放了多个http接口,这些http接口的body都是json格式,不同的接口参数不一样,如下:

获取余额接口 http://xxx.xxx.xxx.xxx:xx/abcd/getBalance

{
“account”:”a1234”,
“pwd”:”asdfg”
}

发送消息接口 http://xxx.xxx.xxx.xxx:xx/abcd/sendMsg

{
“account”:”a1234”,
“pwd”:”asdfg”,
“extend”:”11”,
“compressType”:”1”,
“content”:”测试一下”,
“userList”:”a0001”,
“flag”:”1”
}

定时发送接口 http://xxx.xxx.xxx.xxx:xx/abcd/timerSend

{
“account”:”a1234”,
“pwd”:”asdfg”,
“extend”:”11”,
“compressType”:”1”,
“content”:”测试一下”,
“sendTime”:”2018-11-11 00:00:00”,
“userList”:”a0001,a0002,a0003”
}


于是我写了如下class

class ParseBase // 基类,这里简单写一下
{
public:
  virtual bool parse();
  virtual string getFlag() {return “”;}

  string account;
  string pwd;
  string user;
  string content;
  string extend;
};

class GetBalanceParse : public ParseBase {};

class SendMsgParse : public ParseBase
{
public:
    virtual bool parse()
    {
        ParseBase::parse(); // 这里先调用基类的解析函数
    }

    virtual string getFlag() {return flag;}
    string flag;
};

class TimerSendParse : public ParseBase
{
};

因为在SendMsg接口的业务代码里面,需要获取flag,但是代码中使用的都是基类指针,所以就顺其自然的在基类里面加了个虚函数获取flag字段的值。当然,在其他接口业务代码中,是不会去调用这个getFlag函数的,但这样做也就相当于允许了其他接口的业务代码去调用getFlag函数。


为了复用代码而写的继承体系,违反了适用于base classes身上的每一件事情,也一定适用于derived classes身上的原则。


正确的做法,应该是使用复合(或者组合)来代替。
不采用继承体系,而是写一些容易使用也容易修改的具体类,采用基于对象的设计。如果两个类有共同的代码逻辑,那就考虑一下提炼出一个工具类来用,让代码保持清晰。

class ParseTool; // 原Parse基类改成工具类

class SendMsgParse
{
public:
    ParseTool parseTool; 
};

class TimerSendParse : public ParseBase
{
public:
    ParseTool parseTool; 

};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值