软件设计模式和原则

设计模式是一组模板,可简化软件开发过程,提升代码的质量和一致性。它们按类型分为:创建模式(处理对象创建)、行为模式(定义对象交互方式)和结构模式(用于组织类和对象)。本文重点讨论代理模式,一种结构模式,它充当其他对象的中介,提供统一的访问方

设计模式是一组模板,可简化软件开发过程,提升代码的质量和一致性。它们按类型分为:创建模式(处理对象创建)、行为模式(定义对象交互方式)和结构模式(用于组织类和对象)。本文重点讨论代理模式,一种结构模式,它充当其他对象的中介,提供统一的访问方式并允许灵活控制。代理模式尤其适用于分布式系统,允许客户端与远程服务交互,同时隐藏底层通信细节。

软件设计模式和原则

设计模式是软件架构师在一段时间内制定的一组模板。它们是软件程序员可以应用于自己的软件/应用程序开发的最佳实践。它们通过重用预先存在的解决方案节省时间和精力,同时提高代码的质量和一致性,从而提供了令人难以置信的优势。它还可以帮助增强与其他开发人员的沟通和协作,促进代码的适应和发展,并防止常见的陷阱和错误。总而言之,设计模式是简化编程过程的好方法。 

广义上讲,有三种模式:结构模式,创建模式和行为模式。

创建模式与对象的创建有关,并将对象的创建与使用该对象的客户端分开。示例包括单例、工厂和工厂方法。 

行为模式定义多个对象如何相互作用。命令模式、迭代器模式和观察者模式是一些常见的行为模式。这些模式展示了系统的不同组件如何相互行为和响应。它可以通过增强灵活性、模块化和可重用性来改进代码。

另一方面,结构模式处理类和对象的组成和组织。它可以通过将类和对象组合成更大的结构来隐藏系统的复杂性。示例包括适配器、复合、装饰器、外观和代理。

虽然设计模式是一种久经考验的解决方案,但它们是在良好的面向对象编程原则的基础上形成的。以下列出了一些关键原则:

  • 针对接口进行编程:保持设计的灵活性。

  • 确定软件中可能变化的部分,并将它们与变化的部分分开:保持设计模块化

  • 倾向于组合而不是继承: 用单个对象组成大型结构。

  • 松散耦合: 尽量减少对象的相互依赖。

  • 开放/封闭原则: 类软件一旦代码完成、测试和验证,就应该对修改关闭,但该类可以通过继承的方式对扩展开放。

  • 依赖反转:依赖于抽象或接口而不是类的具体实例。

  • 单一责任原则: 一个类只负责一个需求。

示例:代理模式

我们选择了结构代理模式进行讨论。这是一种流行的模式,尤其在分布式系统中用作远程代理。顾名思义,代理模式是其他人的代理。代理设计的类提供面向公众的 API,客户端可以使用这些 API 发送请求。代理类具有访问真实对象服务的方法,并且可以在对来自客户端的请求进行身份验证之后向其提供请求。此外,代理模式可以允许延迟初始化。如果真实 对象的创建被认为是昂贵的,我们可以仅在客户端需要时延迟其实例化。它还允许日志记录和缓存,这些可以在代理类方法中实现。在分布式系统中,客户端和代理对象位于一个节点上,而为请求提供服务的实际对象位于另一个节点上,代理模式允许统一视图,客户端不知道哪个节点正在为该对象提供服务。 

图 1:代理模式

图 1:代理模式

图 1 显示了代理模式的架构图。它有一个包含ProxyObject句柄的客户端类。ProxyClass和RealClass 都派生自iProxy 接口类并实现 API。为了能够在两个节点之间进行通信,它们都另外有一个CommObject  ,负责在网络上共享 时对命令和数据进行序列化和反序列化。代码片段提供了一组最小的类和方法声明,以直观地展示分布式系统如何协同运行。

// CommClass 提供序列化/反序列化
// 在分布式系统中,共享数据和命令
class CommClass {
  // RealClass 向 CommClass 注册一个回调来接收命令
  // 以及来自代理的数据
  <a style='color:#f60; text-decoration:underline;' href="https://www.php.cn/zt/58423.html" target="_blank">typedef</a> std::function<void(unsigned, vector<unsigned>)> fCallBack;
  
  public:
  CommClass() {}
~CommClass() {}
  // 代理类使用 CommClass 对象向远程服务发送命令和数据
  void sendToRemoteService(unsigned cmd, std::vector<unsigned> data);
   // 远程服务类通过事件通知。它使用已注册的回调
    // 调用远程服务 RealClass
  void receiveFromProxy(unsigned cmd, std::vector<unsigned> data)
    {
    _cb(cmd, data);
    }
  
  void registerCallBack(fCallBack cb) { _cb = cb; }
  
  private:
  fCallBack _cb;
  
};
// 代理接口类声明面向公共的方法
class iProxy {
  public:
  iProxy() {}
  virtual ~iProxy() {}
  
  virtual void methodOne() = 0;
  virtual void methodTwo() = 0;
};
// 实现接口类方法的具体类和
// 与客户端位于同一节点
class ProxyClass : public iProxy {
  public:
  ProxyClass() {};
  ~ProxyClass() {};
  
     // 实现接口
  void methodOne() {};
  void methodTwo() {};
  
  private:
  CommClass CommObject;
  
};
// 实现代理接口方法并作为服务提供者的真实类
class RealClass : public iProxy {
  public:
    RealClass() {};
    ~RealClass() {};
  
    // 实现接口
    void methodOne() {};
    void methodTwo() {};
  private:
  CommClass CommObject;
  
};

登录后复制

结论

示例代理模式是任何软件工程师的箭筒中的重要箭头。通过使用组合原则,我们可以控制对内部对象的访问,添加额外的逻辑(例如缓存和 API 日志记录)以及增加安全性。它允许延迟初始化,这在资源受限的环境中很有用。确实存在某些缺点,例如增加开销和复杂性,因此,这不是一个万能的解决方案。  

虽然代理模式为许多常见的设计挑战提供了强大的解决方案,但任何设计模式都应谨慎使用,以免使您的设计过于复杂。始终从较简单的面向对象原则开始,然后在您的架构开始类似于特定模式时切换到设计模式。

以上就是软件设计模式和原则的详细内容,更多请关注叮当号网其它相关文章!

文章来自互联网,只做分享使用。发布者:木子,转转请注明出处:https://www.dingdanghao.com/article/580065.html

(0)
上一篇 2024-06-06 14:40
下一篇 2024-06-06 14:40

相关推荐

联系我们

在线咨询: QQ交谈

邮件:442814395@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信公众号