精华内容
下载资源
问答
  • 软件设计原则

    2020-08-04 21:10:32
    这七条软件设计原则是我们在进行软件设计开发时尽可能遵循的原则,这七条原则彼此之间的侧重点不同。但一般来说开闭原则是总领一切的。 开闭原则告诉我们要对扩展开放,对修改关闭;,里氏替换原则告诉我们不要破坏...

    软件设计开发中,如果依据软件设计七条原则来开发,可以提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,并提高软件开发效率、节约软件开发与维护成本。

    这七条软件设计原则是我们在进行软件设计开发时尽可能遵循的原则,这七条原则彼此之间的侧重点不同。但一般来说开闭原则是总领一切的。
    开闭原则告诉我们要对扩展开放,对修改关闭;,里氏替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要面向接口编程;单一职责原则告诉我们类的职责要尽可能唯一;接口隔离原则告诉我们在设计接口时要尽可能精简,迪米特法则告诉我要降低耦合度;合成复用原则我们要多用聚合或组合,少用继承关系。

    开闭原则的含义是:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。

    效果:

    • 软件遵守开闭原则的话,软件测试时只需要对扩展的代码进行测试就可以了,因为原有的测试代码仍然能够正常运行。
    • 粒度越小,被复用的可能性就越大;在面向对象的程序设计中,根据原子和抽象编程可以提高代码的可复用性。
    • 遵守开闭原则的软件,其稳定性高和延续性强,从而易于扩展和维护。

    里氏替换原是继承复用的基础,它反映了基类与子类之间的关系,是对开闭原则的补充,是对实现抽象化的具体步骤的规范。通过“抽象约束、封装变化”来实现开闭原则,即通过接口或者抽象类为软件实体定义一个相对稳定的抽象层,而将相同的可变因素封装在相同的具体实现类中。

    效果:

    • 里氏替换原则是实现开闭原则的重要方式之一
    • 它克服了继承中重写父类造成的可复用性变差的缺点
    • 它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性

    依赖倒置原则的原始定义为:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。依赖倒置原则是实现开闭原则的重要途径之一,它降低了客户与实现模块之间的耦合。

    效果:

    • 依赖倒置原则可以降低类间的耦合性。
    • 依赖倒置原则可以提高系统的稳定性。
    • 依赖倒置原则可以减少并行开发引起的风险。
    • 依赖倒置原则可以提高代码的可读性和可维护性。

    单一职责原则规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分。该原则提出对象不应该承担太多职责,否则可能会造成代码的冗余与或者类中的职责互相影响。单一职责原则的核心就是控制类的粒度大小、将对象解耦、提高其内聚性。
    效果:

    • 降低类的复杂度。一个类只负责一项职责
    • 提高类的可读性
    • 提高系统的可维护性
    • 降低变更引起的风险

    接口隔离原则要求程序员尽量将臃肿庞大的接口拆分成更小的和更具体的接口,让接口中只包含客户感兴趣的方法,简单的来说就是要为各个类建立它们需要的专用接口。

    接口隔离原则与单一职责都是为了提高类的内聚性、降低它们之间的耦合性,体现了封装的思想,但有些许不同之处

    • 单一职责原则注重职责:而接口隔离原则注重的是对接口依赖的隔离
    • 单一职责原则主要是约束类,针对程序中的实现,接口隔离则约束接口,针对抽象和程序整体框架的构建。

    效果:

    • 将臃肿庞大的接口分解为多个粒度小的接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。
    • 接口隔离提高了系统的内聚性,减少了对外交互,降低了系统的耦合性。
    • 如果接口的粒度大小定义合理,能够保证系统的稳定性;但是,如果定义过小,则会造成接口数量过多,使设计复杂化;如果定义太大,灵活性降低,无法提供定制服务,给整体项目带来无法预料的风险。
    • 使用多个专门的接口还能够体现对象的层次,因为可以通过接口的继承,实现对总接口的定义。
    • 能减少项目工程中的代码冗余。过大的大接口里面通常放置许多不用的方法,当实现这个接口的时候,被迫设计冗余的代码。

    迪米特法则(最少知识原则)是指如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。

    效果:

    • 降低了类之间的耦合度,提高了模块的相对独立性。
    • 由于亲合度降低,从而提高了类的可复用率和系统的扩展性。

    缺点:产生了大量的中介类,从而增加系统的复杂性,使模块间的通信率降低。

    注意事项:

    • 在类的划分上,应该创建弱耦合的类。类与类之间的耦合越弱,就越有利于实现可复用的目标。
    • 在类的结构设计上,尽量降低类成员的访问权限。
    • 在类的设计上,优先考虑将一个类设置成不变类。
    • 在对其他类的引用上,将引用其他对象的次数降到最低。
    • 不暴露类的属性成员,而应该提供相应的访问器(set 和 get 方法)。

    合成复用原则是指要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。如果一定要使用继承关系,则必须严格遵循里氏替换原则。合成复用原则同里氏替换原则相辅相成的,两者都是开闭原则的具体实现规范。

    缺点:

    • 继承复用破坏了类的封装性
    • 子类与父类的耦合度高
    • 它限制了复用的灵活性

    解决办法将已有对象纳入新对象之中。新对象可以调用已有对象的功能
    效果:

    • 它维持了类的封装性。因为成分对象的内部细节是新对象看不见的
    • 新旧类之间的耦合度低。这种复用所需的依赖较少,新对象存取成分对象的唯一方法是通过成分对象的接口。
    • 复用的灵活性高。这种复用可以在运行时动态进行,新对象可以动态地引用与成分对象类型相同的对象
    展开全文
  • 系统软件设计原则 1.系统设计原则–简介 在这篇文章中,我们将介绍有关软件系统设计原理的综合文章。 软件体系结构对于创建同时实现多个目标所需的复杂软件结构至关重要。 在项目开始时创建正确的软件体系结构,就...

    系统软件设计原则

    1.系统设计原则–简介

    在这篇文章中,我们将介绍有关软件系统设计原理的综合文章。 软件体系结构对于创建同时实现多个目标所需的复杂软件结构至关重要。 在项目开始时创建正确的软件体系结构,就可伸缩性,可用性,可靠性和降低的维护成本而言,从长远来看会带来更好的结果。 错误的软件架构和架构决策可能会导致维护成本增加和系统难以维护。

    让我们看一些最佳的系统设计原则。

    2.关注点分离

    关注点分离是软件设计中最重要的原则,即将您的软件系统分为多个组件,并每个部分构建一次。 关注点分离导致应用程序模块化,而模块化是可伸缩和可维护软件体系结构的关键。

    需要使用尽可能少的重叠功能来分解软件系统。 系统中的每个模块或服务应专注于一组专用功能。 这种方法使理解,开发,维护和增强应用程序变得更加容易。 设计关注点分离的系统有助于以不同的编程语言开发不同的模块。 面向对象编程中的继承和组合功能有助于提高应用程序的模块化。

    模块化的主要优点是:

    2.1可重用性

    模块化使重用代码变得容易。 通用代码可以打包为库,并且可以在多个项目和/或模块中使用。

    2.2可维护性

    对软件应用程序进行模块化后,可以轻松对应用程序进行故障排除,轻松修复所有错误并易于维护。 由于每个组件都是独立的,因此可以轻松缓解依赖性问题。 通过模拟其他依赖关系来测试每个模块也很容易。 模块化可以帮助开发团队提高生产率,因为可以轻松地将开发人员或开发团队之间的工作分开。

    2.3可扩展性

    模块化使模块彼此抽象。 只要保持向后兼容性或创建新版本的API,就可以轻松扩展每个模块的功能或向现有模块添加新功能,而不会对其他模块产生重大影响。 通过创建新的组件或模块,可以轻松添加新功能。

    3.高凝聚力和松散耦合

    内聚性是模块的相关元素属于一起并做一件专门事情的程度。 模块中的所有相关代码应彼此靠近。 这有助于减少处理请求的等待时间。 耦合是指应用程序中不同模块相互依赖的程度。

    耦合是两个系统之间的依赖程度。 使软件组件尽可能松散地耦合,即,每个模块应尽可能独立于其他模块,以使一个系统中的更改对其他组件的影响最小甚至没有影响。 继承是紧密耦合的一个例子。 该组合物是松耦合的一个例子。 减少的耦合导致内聚力的增加。

    4.事件驱动架构

    事件驱动的体系结构可帮助您在后端系统中更改感兴趣的数据项时通知应用程序。 应用程序侦听这些通知并刷新其缓存并采取任何后续措施。 如果客户端应用程序可以处理事件通知,则有助于减少对后端系统的调用次数。

    有几种通知机制可用于应用程序开发。 其中一些是ActiveMQ,RabbitMQ,分布式消息传递系统,例如Kafka等。每个云提供商还提供不同的消息传递/通知服务。

    5.减少客户端请求路径中的处理量

    客户端请求路径中的大量处理导致客户端调用中的延迟增加,并限制了应用程序处理的吞吐量。 最少的处理导致更快的响应,并且应用程序可以用更少的容量处理更多的负载。 通过预先预先计算可能的响应项并将其缓存在分布式缓存中,可以实现最少的处理。 当客户端请求数据项时,可以直接从填充的缓存中获取预先计算的数据。

    6.使用有效的缓存使其具有较高的响应速度

    尽可能使用高速缓存以减少远程服务调用,数据库调用和请求路径中的处理量。 这有助于减少客户端服务呼叫中的延迟。 使用事件通知机制可以使缓存保持温暖,并避免将过时的数据提供给客户端。

    7.分布式系统特征

    分布式系统的设计具有高度的可伸缩性,可靠性,并且可用于应对负载的变化,并且具有高度的可靠性和可用性。 以下是有关这些特征的更多详细信息:

    7.1可扩展性

    可扩展性是系统通过增加其他容量来自动增长和管理需求增长的能力。 缩放有两种类型,垂直缩放和水平缩放。

    7.1.1垂直缩放

    在“垂直扩展”中,您添加了具有更多容量的更高级的硬件,例如更多的RAM,强大的处理器等,以增加应用程序的负载。 垂直扩展的问题在于,容量可以增长多少始终存在限制。 由于硬件成本,这种类型的缩放非常昂贵,并且花费时间来获得新的硬件。 如果要快速扩展应用程序以增加负载,则这种扩展类型不是一个好选择。

    7.1.2水平缩放

    在“水平扩展”中,可以将更多服务器添加到现有容量中,以增加应用程序的负载。 应用程序增加的负载通过负载均衡器分布在群集中的所有服务器上。 如果您想快速增长软件并且成本不高,则这种类型的扩展是最佳选择。

    通过配置更改即可轻松扩展Cloud Environments中的应用程序,配置更改会根据性能监控指标自动将其他服务器添加到群集中。

    7.2可靠性

    系统的可靠性是在给定环境中特定时间段内软件运行失败的概率。 如果系统继续满足客户的请求,即使该系统的一部分出现硬件或软件故障,则该系统也被视为高度可靠。 可以更换任何故障组件,而不会影响客户端请求。

    分布式系统的可靠性可以通过软件组件和数据的冗余来实现,因此任何一个组件或数据容器的丢失都不会导致性能下降或客户端请求失败。 由于软件组件和数据的冗余性,高可靠性导致额外的成本。

    7.3可用性

    可用性是指系统在特定时期内保持运行并继续执行其功能的时间。 如果系统可靠,那么它将自动可用,即它将继续运行。

    7.4简单性

    每个系统的设计都是为了使系统尽可能简单。 系统的简单性带来了许多好处,例如重复使用代码,易于更改,易于添加新功能,易于测试和解决任何生产问题。

    8.使用异步过程

    使用异步处理和并行处理将有助于加快客户端请求并减少请求的总体延迟。 使用RxJava之类的框架来并行处理给定客户端请求中涉及的多个子请求。 尽可能使用异步调用来调用其他系统。 减少客户端请求路径中的调用次数可以提高应用程序的性能,并且可以轻松地扩展应用程序。

    翻译自: https://www.javacodegeeks.com/2019/05/software-system-design-principles.html

    系统软件设计原则

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,208
精华内容 7,683
关键字:

软件设计原则