00003.七大软件架构设计原则

简介: 00003.七大软件架构设计原则

前言

提示:这里可以添加本文要记录的大概内容:

例如:软件设计的七大架构设计,指导着软件设计的。


提示:以下是本篇文章正文内容,下面案例可供参考

一、开闭原则

1.开闭原则的定义

开闭原则(Open-Closed Principle, OCP)指一个软件实体如类,模块和函数应对扩展开放,对修改封闭,即该原则是对软件扩展和修改的一项原则,强调的是用抽象构建框架,用实现扩展细节,目的是提高软件的可复用性和可维护性该原则可以建立稳定灵活的系统,如:版本更新,我们尽可能不修改源码,但是可以增加新功能。

  • 实现开闭原则的核心思想就是面向抽象的编程。

2. 使用开闭原则解决实际问题

  • 如设计一个学生管理系统,该学生管理系统包括对学生信息的存储,包括学生的年龄,性别,学历等。案例代码如下
class CStudentOptImp {
public:
  virtual std::string GetName() = 0;
  virtual int GetAge() = 0;
  virtual std::string GetEducation() = 0;
};
class CStudent: public CStudentOptImp {
public:
  CStudent(const std::string name, const int age, const std::string education) :m_sName(name), m_iAge(age), m_sEducation(education) {
  }
  virtual std::string GetName() {
    return m_sName;
  }
  virtual int GetAge() {
    return m_iAge;
  }
  virtual std::string GetEducation() {
    return m_sEducation;
  }
private:
  std::string m_sName;
  int m_iAge;
  std::string m_sEducation;
};
class CStudentRecord :public CStudent {
public:
  CStudentRecord(const std::string name, const int age, const std::string education, const int record) :CStudent(name, age, education), m_iRecord(record) {
  }
  int GetRecord() {
    return m_iRecord;
  }
private:
  int m_iRecord;
};
void test01() {
  std::shared_ptr<CStudent> p = std::shared_ptr<CStudent>(new CStudent("venus", 26, "硕士"));
  std::cout << "姓名:" << p->GetName() << "\t年龄:" << p->GetAge() << "\t学历:" << p->GetEducation() << std::endl;
}
int main() {
  test01();
  return 0;
}

案例结果如下:

而如果此时增加了学生的成绩信息,就需要修改Student类,这项操作是很不稳定的,因为系统中别的类可能调用了该类,修改可能会导致别的功能出现错误或者bug,因而软件开发过程中需要遵循开闭原则,只能通过添加代码达到目的,而不能通过修改代码。如下,此时可以通过继承,增加代码达到目的。详细代码如下:

class CStudentOptImp {
public:
  virtual std::string GetName() = 0;
  virtual int GetAge() = 0;
  virtual std::string GetEducation() = 0;
};
class CStudent: public CStudentOptImp {
public:
  CStudent(const std::string name, const int age, const std::string education) :m_sName(name), m_iAge(age), m_sEducation(education) {
  }
  virtual std::string GetName() {
    return m_sName;
  }
  virtual int GetAge() {
    return m_iAge;
  }
  virtual std::string GetEducation() {
    return m_sEducation;
  }
private:
  std::string m_sName;
  int m_iAge;
  std::string m_sEducation;
};
class CStudentRecord :public CStudent {
public:
  CStudentRecord(const std::string name, const int age, const std::string education, const int record) :CStudent(name, age, education), m_iRecord(record) {
  }
  int GetRecord() {
    return m_iRecord;
  }
private:
  int m_iRecord;
};
void test01() {
  std::shared_ptr<CStudent> p = std::shared_ptr<CStudent>(new CStudent("venus", 26, "硕士"));
  std::cout << "姓名:" << p->GetName() << "\t年龄:" << p->GetAge() << "\t学历:" << p->GetEducation() << std::endl;
}
void test02() {
  std::shared_ptr<CStudentRecord> p = std::shared_ptr<CStudentRecord>(new CStudentRecord("venus", 26, "硕士", 100));
  std::cout << "姓名:" << p->GetName() << "\t年龄:" << p->GetAge() << "\t学历:" << p->GetEducation() << "\t成绩:" << p->GetRecord() << std::endl;
}
int main() {
  //test01();
  test02();
  return 0;
}
  • 案例结果如下:
  • 最后回顾以下整个开闭原则的类图关系:

二、依赖倒置原则

1.依赖倒置原则的定义

  • 依赖倒置原则(Dependence Inversion Principle,DIP)指设计代码结构时,高层模块不应该依赖底层模块。二者都应该依赖其抽象。抽象不应该依赖细节,细节应该依赖抽象。 通过依赖倒置可以减低类与类之间的耦合性,提高系统的稳定性,提高代码的可读性和可维护性。

2.使用依赖倒置原则解决实际问题

  • 我们以张三丰为例,建立张三丰类如下。
#include <iostream>
class Zhangshanfen {
public:
  void StudyTaiChiSword() {
    std::cout << "学习了太极剑" << std::endl;
  }
  void StudyTaiJiBoxing() {
    std::cout << "学习了太极拳" << std::endl;
  }
};
int test01() {
  std::shared_ptr<Zhangshanfen> p = std::shared_ptr<Zhangshanfen>(new Zhangshanfen);
  p->StudyTaiChiSword();
  p->StudyTaiJiBoxing();
  return 0;
}
int main() {
  test01();
  return 0;
}
  • 上面代码效果:
  • 上面代码,如果当张三丰想学习武当剑法的时候,需要重写该段代码,这样程序就会变得不稳定。因此可以考虑将各种武功抽象出来,形成一个抽象类。代码如下:
#include <iostream>
class Kungfu {
public:
  virtual void Study() = 0;
};
class TaiJiSword: public Kungfu {
public:
  virtual void Study() override {
    std::cout << "学习太极剑" << std::endl;
  }
};
class TaiJiBoxing :public Kungfu {
public:
  virtual void Study() override {
    std::cout << "学习太极拳" << std::endl;
  }
};
class WudangSwordTechnique :public Kungfu {
public:
  virtual void Study() override {
    std::cout << "学习武当剑法" << std::endl;
  }
};
class Zhangshanfen {
public:
  void Study(Kungfu* kungfu) {
    kungfu->Study();
  }
};
int test01() {
  Zhangshanfen* p = new Zhangshanfen();
  p->Study(new TaiJiSword);
  p->Study(new TaiJiBoxing);
  p->Study(new WudangSwordTechnique);
  return 0;
}
int main() {
  test01();
  return 0;
}

该代码的演示效果如下:


  • 这个时候不管张三丰想学什么新的武功,对于新的武功,只需要新建一个类,通过传参的方式告诉张三丰,而不需要修改底层代码。实际上,这是一种大家非常熟悉的方式, 叫做依赖注入。此外注入的方式还有构造器注入方式和Setter注入方式,下面来看构造器注入方式。
class Zhangshanfen {
public:
  Zhangshanfen(Kungfu* kunfu) {
    this->kunfu = kunfu;
  }
  void Study() {
    this->kunfu->Study();
  }
private:
  Kungfu* kunfu;
};
  • 测试代码如下
int test01() {
  Zhangshanfen* p = new Zhangshanfen(new TaiJiSword);
  p->Study();
  return 0;
}
  • 根据构造器注入方式,当调用时,每次都要创建实例,那么如果张三丰是全局单例,则只能使用Setter注入方式。代码如下:
class Zhangshanfen {
public:
  void setter(Kungfu* kungfu) {
    this->kungfu = kungfu;
  }
  void Study() {
    this->kungfu->Study();
  }
private:
  Kungfu* kungfu;
};
  • 测试端代码如下:
int test01() {
  Zhangshanfen* p = new Zhangshanfen();
  p->setter(new TaiJiBoxing);
  p->Study();
  return 0;
}
  • 最终得到UML类图如下:

总结

提示:这里对文章进行总结:

例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

目录
相关文章
|
29天前
|
监控 Cloud Native 持续交付
云原生时代的微服务架构设计原则与实践
【9月更文挑战第27天】本文深入探讨了在云原生环境下,如何高效地实施微服务架构。通过分析微服务的基本概念、设计原则和关键技术,结合实际案例,指导读者理解并应用微服务架构于云计算项目之中。文章旨在为软件开发者和架构师提供一条清晰的路径,以实现更加灵活、可扩展且易于维护的系统。
|
17天前
|
Cloud Native 持续交付 数据安全/隐私保护
云原生时代的微服务架构设计原则
在数字化浪潮中,企业纷纷上云以获得更大的灵活性和扩展性。云原生技术因此成为现代软件开发的核心。本文将深入探讨在云原生环境下如何设计高效、可靠的微服务架构,涵盖关键设计原则、最佳实践以及面临的挑战。我们将通过实际案例分析,揭示如何在云原生生态中构建和维护微服务,确保系统的稳定性和可维护性。
|
2月前
|
分布式计算 负载均衡 API
微服务架构设计原则与模式
【8月更文第29天】随着云计算和分布式计算的发展,微服务架构已成为构建大型复杂应用的一种流行方式。这种架构模式将单个应用程序分解成一组小型、独立的服务,每个服务运行在其自己的进程中,并通过轻量级机制(通常是HTTP资源API)进行通信。本文将探讨微服务架构的基本设计原则、常用模式以及如何有效地划分服务边界。
231 3
|
2月前
|
消息中间件 监控 API
深入浅出微服务架构设计原则
在软件开发的宇宙中,微服务如星辰般璀璨,引领着分布式系统的航向。本文将带你穿梭于微服务的星系,探索其背后的设计哲学与实践精髓,从服务边界的划分到数据一致性的保障,再到服务的通信与协作,我们将一同揭开微服务架构高效、可扩展且灵活的秘密。
44 4
|
2月前
|
消息中间件 设计模式 API
后端开发中的微服务架构设计原则
【8月更文挑战第13天】在软件工程的世界中,微服务架构已经成为一种流行的设计模式,它通过将复杂的应用程序分解成一组小的服务来简化开发和部署。本文探讨了微服务背后的设计理念,以及如何在后端开发实践中应用这些原则来构建可扩展、灵活且易于维护的系统。我们将深入讨论服务的划分、通信协议的选择、数据一致性的保障以及容错性策略的实施,旨在为后端开发人员提供一套实用的微服务架构设计指导。
54 1
|
5月前
|
数据中心 网络架构 Python
【计算巢】数据中心的网络架构设计原则
【5月更文挑战第31天】探讨数据中心网络架构设计原则:稳定性是基础,需抵御各种挑战;强调扩展性,适应业务发展;追求高效,确保数据传输速度;注重灵活性,灵活应对变化。简单Python代码示例展示网络节点连接。设计时需具备长远眼光,综合考虑技术方案,以构建坚固高效的信息桥梁。同学们,要持续学习和探索,为信息世界贡献力量!
78 2
|
5月前
|
监控 安全 API
微服务架构下的API网关设计原则
【5月更文挑战第31天】在本文中,我们将深入探讨微服务架构下API网关的设计原则。API网关作为微服务架构的入口点,其设计至关重要。我们将从性能、安全性、可扩展性等方面进行分析,并提出一些实用的设计建议。
|
5月前
|
存储 缓存 运维
云计算架构设计原则
【4月更文挑战第6天】这篇文章介绍了基于云计算的架构设计六大原则:合理部署、业务持续、弹性扩展、性能效率、安全合规和持续运营。
|
设计模式 关系型数据库 数据安全/隐私保护
软件架构设计原则之单一职责原则
单一职责(Simple Responsibility Pinciple,SRP)是指不要存在多于一个导致类变更的原因。假设我们有一个类负责两个职责,一旦发生需求变更,修改其中一个职责的逻辑代码,有可能导致另一个职责的功能发生故障。这样一来,这个类就存在两个导致类变更的原因。如何解决这个问题呢?将两个职责用两个类来实现,进行解耦。后期需求变更维护互不影响。这样的设计,可以降低类的复杂度,提高类的可读性,提高系统的可维护性,降低变更引起的风险。总体来说,就是一个类、接口或方法只负责一项职责。
109 0
软件架构设计原则之单一职责原则
|
设计模式 人工智能 Java
软件架构设计原则之依赖倒置原则
依赖倒置原则(Dependence Inversion Principle,DIP)是指设计代码结构时,高层模块不应该依赖低层模块,二者都应该依赖其抽象。抽象不应该依赖细节,细节应该依赖抽象。通过依赖倒置,可以减少类与类之间的耦合性,提高系统的稳定性,提高代码的可读性和可维护性,并且能够降低修改程序所造成的风险。接下来看一个案例,还是以Course(课程)为例,先来创建一个类Tom:
87 0