Feature of Good Design (1) 优秀设计的特点(一)

Code reuse 代码复用

– Challenge: tight coupling between components, dependencies on concrete classes instead of interfaces, hardcoded operations

– Solution: design patterns

– 挑战:组件之间的紧密耦合、对具体类而不是接口的依赖、硬编码操作

– 解决方案:设计模式

• However, sometimes making components more complicated

然而,有时会使组件变得更加复杂

– Three levels of reuse: a piece of wisdom from Erich Gamma

– 三个层次的重用:Erich Gamma 的智慧

• Lowest: classes

最低:类

• Highest: frameworks

最高:框架

• Middle level: design patterns

中层:设计模式

Feature of Good Design (2) 优秀设计的特点(二)

Extensibility 可扩展性

Change is the only constant thing in a programmer’s life

– 变化是程序员一生中唯一不变的事情

• We understand the problem better once we start to solve it

一旦我们开始解决问题,我们就会更好地理解问题

• Something beyond your control has changed

你无法控制的事情已经发生了变化

• Objectives/requirements have changed

目标/要求已改变

– Prepare for possible future changes when designing an architecture

– 设计结构时为未来可能发生的变化做好准备

Good Design Principles (1) 良好的设计原则(1)

Encapsulate what varies 封装不同的内容

– Identify the aspects of your application that vary, and separate them from what stays the same

– 识别应用程序中不同的方面,并将它们与保持不变的部分区分开来

– Main goal: minimize the effect caused by changes

– 主要目标:最小化变化造成的影响

– Isolating program parts that vary in independent modules, protecting the rest

-隔离独立模块中不同的程序部分,保护其余部分

– Encapsulation on a method level

– 方法级别的封装

– Encapsulation on a class level

– 类级别的封装

Good Design Principles (2) 良好的设计原则(2)

Program to an interface, not an implementation 对接口编程,而不是实现

– In other words, depend on abstractions, not on concrete classes

– 换句话说,依赖于抽象,而不是具体的类

– The design is flexible enough if you can easily extend it without breaking existing code

– 如果您可以轻松地扩展它而无需破坏现有代码,那么该设计就足够灵活

– A possible approach

  1. Determine what exactly one object needs from the other: which methods does it execute?

    确定一个对象到底需要另一个对象什么:它执行哪些方法?
  2. Describe these methods in a new interface or abstract class.

    在新的接口或抽象类中描述这些方法。
  3. Make the class that is a dependency implement this interface.

    使作为依赖项的类实现此接口。
  4. Make the second class dependent on this interface rather than on the

    concrete class.

    使第二个类依赖于该接口而不是具体的类。

Good Design Principles (3) 良好的设计原则(3)

Favor composition over inheritance 优先考虑组合而不是继承

– Challenge of inheritance

– 继承的挑战

• A subclass can’t reduce the interface of the superclass

子类不能减少超类的接口

• When overriding methods you need to make sure that the new behavior is compatible with the base one

重写方法时,您需要确保新行为与基本行为兼容

• Inheritance breaks encapsulation of the superclass

继承破坏了超类的封装

• Subclasses are tightly coupled to superclasses

子类与超类紧密耦合

• Trying to reuse code through inheritance can lead to creating parallel inheritance hierarchies

尝试通过继承重用代码可能会导致创建并行继承层次结构

SOLID Principles

SOLID 1: Single Responsibility Principle 单一职责原则

A class should have just one reason to change

一个类应该只有一个改变的理由

– Try to make every class responsible for a single part of functionality,and make that responsibility entirely encapsulated

– 尝试让每个类负责一部分功能,并完全封装该职责

• Main goal: reducing complexity, and reducing risks

主要目标:降低复杂性并降低风险

SOLID 2: Open/Closed Principle 开闭原理

  • Classes should be open for extension but closed for modification

    类应该对扩展开放,但对修改关闭

    – Keep existing code from breaking when implementing new features

    – 在实现新功能时防止现有代码被破坏
  • A class is open if it can be extended by subclasses

    如果一个类可以通过子类扩展,则该类是开放的
  • A class is closed if it is 100% ready to be used by others

    如果一个类 100% 可供其他人使用,则该类已关闭
  • A class can be both open (for extension) and closed (for modification) at the same time

    一个类可以同时开放(用于扩展)和封闭(用于修改)

    – Not necessary to be applied for all changes

    – 无需应用所有变更

SOLID 3:Liskov Substitution Principle 里氏替换原理

  • When extending a class, ensure the capability of passing objects of the subclass in place of objects of the parent class without breaking the client code

    扩展类时,保证能够通过子类的对象代替父类的对象,而不破坏客户端代码

  • The subclass should remain compatible with the behavior of the superclass

    子类应该与超类的行为保持兼容

    – When overriding a method, extend the base behavior rather than replacing it with something else entirely

    重写方法时,扩展基本行为而不是完全用其他东西替换它

  • Especially critical when developing libraries and frameworks

    在开发库和框架时尤其重要

  • A set of checks

    一组检查

    • (a) Parameter types in a method of a subclass should match or be more abstract than parameter types in the method of the superclass.

      子类方法中的参数类型应与超类方法中的参数类型匹配或更抽象。
    • (b) The return type in a method of a subclass should match or be a subtype of the return type in the method of the superclass.

      子类方法中的返回类型应该与超类方法中的返回类型匹配或者是其子类型。
    • (c) Types of exceptions should match or be subtypes of the ones that the base method is already able to throw.

      异常类型应该与基方法已经能够抛出的异常类型匹配或者是其子类型。
    • (d) A subclass shouldn’t strengthen pre-conditions.

      子类不应强化先决条件
    • (e) A subclass shouldn’t weaken post-conditions.

      子类不应削弱后置条件
    • (f) Invariants of a superclass must be preserved (least formal rule of all)

      必须保留超类的不变量(至少所有正式规则)
    • (g) A subclass shouldn’t change values of private fields of the superclass.

      子类不应更改超类的私有字段的值。

SOLID 4: Interface Segregation Principle 接口隔离原则

Clients shouldn’t be forced to depend on methods they do not use

不应强迫实现代码依赖他们不使用的方法

– Make interfaces narrow enough that client classes don’t have to implement

behaviors they don’t need

– 使接口足够窄,以便实现代码类不必实现它们不需要的行为

– Break down “fat” interfaces into more granular and specific ones

– 将“胖”接口分解为更细粒度和更具体的接口

SOLID 5: Dependency Inversion Principle 依赖倒置原则

  • High-level classes shouldn’t depend on low-level classes, and both should depend on abstractions

    高级别的类不应该依赖于低级别的类,并且两者都应该依赖于抽象
  • Problem: business logic classes tend to become dependent on primitive low-level classes

    问题:业务逻辑类往往会依赖于原始的低级类
  • Suggestion: changing the direction of dependency

    建议:改变依赖方向
  • Approach
    • Describe interfaces for low-level operations that high-level classes rely on, preferably in business terms

      描述高级类所依赖的低级操作的接口,最好用业务术语
    • Make high-level classes dependent on the interfaces, resulting in a softer dependency

      使高级类依赖于接口,从而产生更软的依赖关系
    • Low-level classes implement the interfaces, dependent on the business logic level

      低级类实现接口,依赖于业务逻辑级别

学习高校课程-软件设计模式-软件设计原则(lec2)的更多相关文章

  1. 敏捷软件开发_设计原则<三>

    敏捷软件开发_设计原则 单一职责原则(single responsibilities principle,SRP) 原理:一个类应该只有一个变化 分离职责:如果不耦合的职责那么很简单,如果两个职责耦合 ...

  2. 设计模式学习(二):面向对象设计原则与UML类图

    一.UML类图和面向对象设计原则简介 在学习设计模式之前,需要找我一些预备知识,主要包括UML类图和面向对象设计原则. UML类图可用于描述每一个设计模式的结构以及对模式实例进行说明,而模式结构又是设 ...

  3. JavaScript设计模式之设计原则

    何为设计 即按照哪一种思路或者标准来实现功能,功能相同,可以有不同的设计方案来实现 伴随着需求的增加,设计的作用就会体现出来,一般的APP每天都在变化,更新很快,需求不断在增加,如果设计的不好,后面很 ...

  4. Java设计模式 —— 面向对象设计原则

    1 设计模式概述 1.1 设计模式的定义与分类 设计模式的定义 Design patterns are descriptions of communicating objects and classe ...

  5. java设计模式和设计原则

    一.创建型模式 1.抽象工厂模式(Abstract factory pattern): 提供一个接口, 用于创建相关或依赖对象的家族, 而不需要指定具体类.2.生成器模式(Builder patter ...

  6. 设计模式之设计原则 C#

    成为一名资深架构师首先要懂设计模式,在懂之前,要清楚设计原则,原来我就吃过这个亏,很久以前有人问我设计原则,我是一头茫然,不是只有设计模式吗?且不知设计原则就像是写书法一样,楷体就是方正,竖道有垂露等 ...

  7. 设计模式——<面向对象设计原则以及23种设计模式分类>

    一.面向对象八大设计原则: 1.依赖倒置原则(DIP) 高层模块(稳定)不应该依赖于低层模块(变化),二者都应该依赖于抽象(稳定) . 抽象(稳定)不应该依赖于实现细节(变化) ,实现细节应该依赖于抽 ...

  8. 设计模式学习系列(一)——IOC设计原则

    参考转载自IoC 之 2.1 IoC基础 ——跟我学Spring3

  9. JAVA设计模式及其设计原则

    设计模式: 设计模式是一套被反复使用的.多数人知晓的.经过分类编目的.代码设计经验的总结. 单例模式:在一个jvm虚拟机,要创建的对象控制成独一份:举例:统计单台虚拟机内的用户在线数 package ...

  10. 年终知识分享——UML、设计模式、设计原则

                                                                                                        ...

随机推荐

  1. Solo 开发者周刊 (第6期):仅需一个动作,秒变时间管理大师?

    这里会整合 Solo 社区每周推广内容.产品模块或活动投稿,每周五发布.在这期周刊中,我们将深入探讨开源软件产品的开发旅程,分享来自一线独立开发者的经验和见解.本杂志开源,欢迎投稿. 产品推荐 1. ...

  2. 可视化—AntV G6实现节点连线及展开收缩分组

    AntV 是蚂蚁金服全新一代数据可视化解决方案,主要包含数据驱动的高交互可视化图形语法G2,专注解决流程与关系分析的图表库 G6.适于对性能.体积.扩展性要求严苛的场景. demo使用数字模拟真实的节 ...

  3. 记录一下实习的第一次线下面试的答辩经历,关于seata|sentinel,gateway与栈

    面的一家小公司,他们准备做单体架构升级到微服务,所以问了我一些微服务相关的东西.回答的依托答辩,今天回想起来记录一下我造出来的笑话,正常的就不写在这里了. 首先我简历上大部分写的是熟悉,只有微服务写的 ...

  4. nacos启动失败:No DataSource set

    通过docker查看nacos的日志发现nacos好端端的突然不能用了 docker logs nacos 报错后说是no datasource set,我看了我在docker里的MySQL是正常启动 ...

  5. 写写Redis十大类型hyperloglog(基数统计)的常用命令

    hyperloglog处理问题的关键所在和bitmap差不多,都是为了减少对sql的写操作,提高性能,用于基数统计的算法.基数就是一种数据集,用于收集去重后内容的数量.会有0.81%的误差 hyper ...

  6. 记hashmap

    hashmap是map接口的一个实现类,在同步的情况下hashmap的性能是比较好的 hashmap就是一个kv键值对的集合,将数值散列均匀的存储在哈希表中.插入方法为map.put(k,v),读取方 ...

  7. PKUWC2024游记

    PKUWC2024 游记 day -???? 得知今年冬令营在育才,非常高兴不用出远门了. day 1 当天上午 7:00 起来,然后做车去报道,非常堵车.感觉育才环境挺好的,~不像某人在读学校一样. ...

  8. Java8 Stream流使用

    Java8 Stream 流式编程 一.Lambda表达式 Lambda表达式也可以称为闭包,它是推动Java8发布的最重要新特性,lambda允许把函数作为一个方法参数传递给方法. 在Java8之前 ...

  9. 【Spring】使用SpringTest报错 java.lang.NoSuchMethodError

    完整报错信息: "C:\Program Files\Java\jdk1.8.0_301\bin\java.exe" -ea -Didea.test.cyclic.buffer.si ...

  10. 【Web】 通过浏览器打开本地应用程序

    首先需要编写注册表: 以Steam为例: "C:\Program Files (x86)\Steam\Steam.exe" 然后编写注册表: Windows Registry Ed ...