Jason Pan

相似类的实现方式比较

黄杰 / 2020-07-02


方式一:类模板

实际使用的【简单工厂模式】( Simple Factory Pattern )

好客的连接池管理,针对Redis、Mysql、Tlog等多种不同的类型,定义类模板,然后使用不同的Client作为形参来实例化不同类型的连接池。

1. 定义一个模板

template<typename StoreSmartPtr, typename StoreSmartPtrMgt>
class StorePtrMgt
{
public:
    StorePtrMgt(StoreSmartPtr ptr) {
        m_ptr = ptr;
        m_conn_status = ConnStatus_OK;
    }

2. 使用模板形参

template<typename StoreSmartPtr, typename StoreClsName>
bool StoreClientMgt<StoreSmartPtr, StoreClsName>::get_new_connect(
    const STORE_LBTYPE lb_type,
    const StoreServerInfo &store_server_info,
    const StoreTimeoutConf &store_timeout,
    StoreSmartPtr &ptr,
    const int cluster_idx)
{
    ptr = new StoreClsName();
    int ret = ptr->init(server_info, store_timeout);
    ...

3. 实例化模板

typedef StoreClientMgt<CdbClient_Ptr, CdbClient> CdbClientMgt;
typedef StoreClientMgt<DummyQueue_Ptr, DummyQueue> RedisClientMgt;

方式二: 虚函数

MSDK V5 login模块,使用的简单工厂模式,根据不同的渠道ID,来创建不同的Msg对象。

switch (channel) {
case itop::CHANNEL_WeChat:
    msg = new WeixinLoginMsg;
    break;
case itop::CHANNEL_Mqq:
    msg = new MqqLoginMsg;
    break;
case itop::CHANNEL_Guest:
    msg = new GuestLoginMsg;
    break;
case itop::CHANNEL_Facebook:
    msg = new FacebookLoginMsg;
    break;

类的继承关系:

object WeixinLoginMsg
object LoginMsg
object ItopBaseMsg
object CSyncMsg

CSyncMsg <|-- ItopBaseMsg
ItopBaseMsg <|-- LoginMsg
LoginMsg <|-- WeixinLoginMsg

方式三:工厂模式

自建账号系统的SPP Msg的HandleProcess中,创建Dispatcher,而Dispatcher中又调用DispatchFromHttp来创建继承自BaseHandler的对象。

因为Dispatcher没有继承抽象的工厂父类,所以也只能算是简单工厂模式,而不是工厂方法模式。

int SAccMsg::HandleProcess() {
  int ret = HandleRequest();
  if (ret) {
    ret_code_ = ret;
    ret_msg_oss_ << " #handle request fail, ret[" << ret << "]";
    return HandleError();
  }
  
  dspt_ptr_ = new Dispatcher(this);
  if (NULL != dspt_ptr_) {
    if (NULL != http_resolver_ptr_) {
      cmdid_ = http_resolver_ptr_->cmdid_;
      handler_ptr_ = dspt_ptr_->DispatchFromHTTP(http_resolver_ptr_);
...

BaseHandler* Dispatcher::DispatchFromHTTP(HTTPResolver* http) {
  BaseHandler* handler = NULL;
  switch (http->cmdid_) {
    case kCMDLogin:
      handler = new LoginHandler();
      break

涉及到设计模式的相关概念

Q: 什么术语描述“相似类的实现” A: Strategy Pattern

策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。

策略模式:

简明的设计模式

https://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html