当前位置: 首页 > article >正文

设计心得——解耦的实现技术

一、说明

在前面的“设计心得——解耦”中,对解耦进行了高层次的抽象说明。本篇则对在实践中常用的解耦技术进行逐一分析说明,以期为开发者能更从理论到实践搭建一个桥梁。至于大家能够如何更好的在自己的项目中进行解耦的实践,就需要不断的进行总结分析,有一个否定之否定的过程。

二、解耦的技术

实现解耦的技术和手段非常多,常见的有以下几种:
1、抽象接口
通过接口来实现类间的解耦是非常常见的手段,在C++中一般是使用抽象类中的纯虚函数来进行接口抽象。通过具体的实现类来完成抽象接口中的统一接口,从而达到解耦的目的。类似下面的这种:

#include <iostream>
#include <memory>

// 抽象接口类 Shape
class Shape {
public:
    virtual void draw() const = 0;
    virtual ~Shape() = default;
};

// 子类Circle
class Circle : public Shape {
public:
    void draw() const override {
        std::cout << "Drawing a Circle" << std::endl;
    }
};

// 子类 Rectangle
class Rectangle : public Shape {
public:
    void draw() const override {
        std::cout << "Drawing a Rectangle" << std::endl;
    }
};

void drawShape(const std::shared_ptr<Shape>& shape) {
    shape->draw();
}

int main() {
    auto circle = std::make_shared<Circle>();
    auto rectangle = std::make_shared<Rectangle>();

    drawShape(circle);
    drawShape(rectangle);

    return 0;
}

例程简单明了,一眼就能看出来接口的意思。另外模块间的API接口其实也可以划到这部分:

int open(const char *pathname, int flags, mode_t mode);

Linux系统的文件打开API函数。
2、设计模式
在设计模式中提供了一些解耦的手段,如工厂模式、策略模式和命令模式等等

#include <iostream>
#include <memory>
//接口抽象
class MoveStrategy {
public:
    virtual ~MoveStrategy() = default;
    virtual void move() const = 0;
};
//具体策略
class WalkStrategy : public MoveStrategy {
public:
    void move() const override {
        std::cout << "The Role is walking." << std::endl;
    }
};

class RunStrategy : public MoveStrategy {
public:
    void move() const override {
        std::cout << "The Role is running." << std::endl;
    }
};

class JumpStrategy : public MoveStrategy {
public:
    void move() const override {
        std::cout << "The Role is jumping." << std::endl;
    }
};
//角色类
class Role {
private:
    std::shared_ptr<MoveStrategy> moveStrategy;

public:
    Role(std::shared_ptr<MoveStrategy> strategy)
        : moveStrategy(std::move(strategy)) {}

    void setMoveStrategy(std::shared_ptr<MoveStrategy> strategy) {
        moveStrategy = std::move(strategy);
    }

    void move() const {
        moveStrategy->move();
    }
};
int main() {
    // 创建角色,并设置其移动策略
    auto role = std::make_shared<Role>(std::make_shared<WalkStrategy>());
    role->move();

    //使用跑动策略
    role->setMoveStrategy(std::make_shared<RunStrategy>());
    role->move();

    //使用跳跃策略
    role->setMoveStrategy(std::make_shared<JumpStrategy>());
    role->move();

    return 0;
}

其它设计模式基本的方法类似。
3、控制反转(依赖注入)
这个例子非常多,前面也刚刚分析过就不再举例了。
4、泛型编程(模板编程 )
模板编程的优势在于适应性更强,编码灵活,便于优化,但使用不当可能会引起代码膨胀等问题。但最主要的是引入的复杂性,要根据情况取舍,看一个简单的比较处理:

#include <iostream>
#include <type_traits>

template <typename T>
decltype(auto) compare(const T& a, const T& b)  {
    return a < b;
}

struct MyType {
    int value;
    MyType(int v) : value(v) {}
    bool operator<(const MyType& other) const {
        return value < other.value;
    }
};

int main() {
    int x = 5, y = 10;
    double a = 3.14, b = 2.71;
    MyType m1(1), m2(2);

    compare(x,y);
    compare(a,b);
    compare(m1,m2);

    return 0;
}

5、服务隔离
也就常提到的面向服务编程,包括消息队列服务、流服务和远程服务

//services
class PostProcess(http_request request){
virtual std::string recvRequest(http_request request) = 0;
};
class PostPlatform(http_request request):public PostProcess{
virtual std::string recvRequest(http_request request){
  std::cout<<"Platform recv request!"<<std::endl;
  return "platform";
}
};
class PostMerchant(http_request request):public PostProcess{
virtual std::string recvRequest(http_request request){
 std::cout<<"Merchant recv request!"<<std::endl;
 return "merchant";
}
};
//client
std::string sendRequest(PostProcess *p,http_request request){
   auto s = p->recvRequest(request)
   return s;
}
int main() {
    PostPlatform pp;
    http_request request("exchange goods");

    sendRequest(&pp,request);

    return 0;
}

6、其它
这一其它就多了,不过除了上面那几个技术,象COM技术、插件技术等等都是用得虽然不多,但名气可不小的。此处就不再举例 ,有兴趣的可以看看一些开源框架或源码,如MySql的源码中就使用了插件技术。

三、比较和应用

在上面的几种解耦技术中,对大多数C++程序员来说,经常使用的还是在前四个居多。但无论哪种应用,一个前提就是不能太复杂,所以泛型编程可能对很多小伙伴来说就又被剔除了。而控制反转和设计模式一般来说都和一定场景有关,所以最后留下来的,就是一个,抽象接口来实现解耦。
或者回过头来说,抽象接口是后面所有的解耦手段的基础,掌握了接口抽象的能力,就具备在设计层次向更高一层前进的能力。

四、总结

设计是一个不断沉淀的过程,没有人可能一下就掌握了设计的全部精髓。这就和一个人的成长一样,从婴儿到成为一个健硕的青年,中间可能会经过无数的大大小小的错误,既有身体疾病上的成长的过程,也有思想不断成熟的过程。
所以,设计只是一个人思想的外延。它既受主观的影响也受外面客观的实践的影响。


http://www.kler.cn/a/557847.html

相关文章:

  • 打开Firefox自动打开hao360.hjttif.com标签解决方案
  • java Web
  • 【论文解析】Fast prediction mode selection and CU partition for HEVC intra coding
  • 【漫话机器学习系列】100.L2 范数(L2 Norm,欧几里得范数)
  • .NET MVC实现电影票管理
  • 电商API安全防护:JWT令牌与XSS防御实战
  • android 快速定位当前页面
  • 设计模式之组合设计模式实战 文件展示 树叶子节点
  • chrome扩展程序如何实现国际化
  • springboot3.x整合fastdfs
  • Wireshark详解
  • cs106x-lecture14(Autumn 2017)-SPL实现
  • Python Matplotlib图形美化指南
  • C#DevExpress使用GridLookUpEdit实现订单明细选择商品
  • vue3 文件类型传Form Data数据格式给后端
  • 《[含文档+PPT+源码等]精品基于Python实现的Django中药材在线学习系统的设计与实现
  • 和平之翼代码生成器 SHCEU 版 4.0.0RC6 千年隼介绍二
  • 通过wifi无线方式,通过adb命令连接手机,用来传输文件和安装app
  • Open WebUI选择模型为空,解决办法(for DeepSeek)
  • Ubuntu 下 nginx-1.24.0 源码分析 - ngx_atoi 函数