软件构造体会(四) 关于五大原则的复习总结

​ 我们在软件构造第八节以及第九节的课堂中学习了JAVA中的五大原则,即SOLID原则,其中lsp原则我们接触的比较多而且接触的还比较早,剩下四个也都有着不同的特点,接下来我们将主要对这些原则的特点,以及在各个场景的适用情况,进行详细的阐释,将我在复习中的心得与一些感悟总结如下

一.单一责任原则(SRP)

​ 内容:类或模块只有一个职责。也就是说,模块、类或方法不应该承担太多工作。

​ 这个原则要求我们当设计一个类时不应该把它设计成一个大的、完整的类,而应该把它设计成一个小的、单功能的类。如果一个类有两个或更多不相关的函数,那么我们就说它违反了单一责任的原则,应该用一个函数和更细的划分为多个类。

​ 我们课件中指出,如果书写的的类过于庞大,则有可能会导致功能实现的降低,如果一个类包含了多个责任,那么将引起不良后果:引入额外的包,占据资源,导致频繁的重新配置、部署等。

​ 在编写程序时我们可以简单的设计一个广泛的类,然后随着业务的发展对其进行重构,而不是遵循严格的规则。

​ 我们在写代码时可以按照以下建议进行代码重构或设计:

​ 1.当一个类过于依赖另一个类,或者直接依赖于它的代码过于复杂不适合高内聚、低耦合的设计理念时可以考虑拆分代码。

​ 2.当类的名称与实际函数无关或没有任何关联时,可以将其更精细地分割并与不相关的函数隔离。

3.当一个类的代码函数太多会影响代码的可读性和维护时,我们可以在方法级别拆分代码。
如下面的代码:

interface Modem {   //反例
	public void dial(String pno);
	public void hangup();
	public void send(char c);
	public char recv();
}
interface DataChannel {//符合SRP原则的代码
	public void send(char c);
	public char recv();
}
interface Connection {
	public void dial(String phn);
	public char hangup();
}

二.开闭原则(OCP):

内容:软件实体(模块、类、函数等)应该是对扩展开放,对修改关闭,简单说就是添加特性应该是现有代码的扩展,而不是对现有代码的修改。

​ 我们可以知道开闭原则的目的是使代码变为可扩展的,避免更改软件中现有代码的风险。可扩展性要求理解在以后可能的扩展点:

​ 1. 如果它是一个业务驱动的系统,需要的前提下充分理解业务需求,我们可以找到相应的扩展点,如果太多的不确定性,需求变化太快,则可以对于一些比较确定的,短期内就可能会扩展,可能在短期内,通过扩展点的设计,可以显著提高开发的稳定性和效率进行设计代码。

​ 2. 对于通用技术开发,如开发通用框架、组件和库,需要考虑用户将如何使用框架,哪些扩展点保留用于功能升级,以及版本之间的兼容性问题。

public void drawShape(Shape s) {//反例
	if (s.m_type==1)
	drawRectangle(s);
	else if (s.m_type==2)
	drawCircle(s);
}
public void drawCircle(Circle r){
	....}
public void drawRectangle(Rectangle r){
	....}
}
class GraphicEditor {//正确做法
	public void drawShape(Shape s) {
		s.draw();
	}
	}
	class Shape {
		abstract void draw();
	}
	class Rectangle extends Shape {
		public void draw() {
		// draw the rectangle
	}
}

三.里氏替换原则(LSP):

定义:子类对象可以在任何地方替换父类对象,并确保原始程序逻辑行为和正确性不被破坏。若A是B的子类型,则B类型的对象可以替换为A类型的对象,使用父类引用指针的程序/函数则能够使用派生类的对象。

可以通过使用面向对象编程的多态性来实现。多态性和里氏替换原则是相似的,但是他们的关注点是不一样的。多态是面向对象编程的特点之一,里氏替换是一种设计原则,用于指导如何继承设计子类,在设计子类时确保替换父类,不改变原程序逻辑,不破坏原程序的正确性。

这个实现可以理解为:当一个子类被设计时,它应该遵循父类的行为约定。父类定义了方法的行为。子类可以改变方法的内部实现逻辑,但它不能改变方法的行为约定,比如接口/方法声明做什么,关于参数值、返回值、异常的约定,甚至是注释中列出的任何特殊指令。

class Rectangle {//如下便为一个例子
    int h, w;
    Rectangle(int h, int w) {
        this.h = h;
        this.w = w;
    }
    void scale(int factor) {
        w = w * factor;
        h = h * factor;
    }

    void setWidth(int neww) {
        w = neww;
    }
}
class Square extends Rectangle {
    Square(int w) {
        super(w, w);
    }

四.接口隔离原理(ISP):

内容:不应该强迫客户端依赖于它不需要的接口

接口隔离原理可以采用如下方法:

  1. 在接口的情况下,如果一个接口假设了一个与它无关的接口定义,则称该接口违反了接口隔离原则,可以去掉无关的接口。

  2. 对于通用功能,应该对程序细分特性,并根据需要添加它们,而不是定义一个大型而全面的接口,让子类强制实现。

interface Worker {//反例
    void work();

    void eat();
}

interface Workable {
    public void work();
}
ManWorker implements Worker{
        void work(){};
        void eat(){};
        }
        RobotWorker implements Worker{
        void work(){};
        void eat(){//Not Appliciable
        for a RobotWorker};
        }

interface Feedable {
    public void eat();
}
interface Workable {//修改后
    public void work();
}

interface Feedable {
    public void eat();
}
ManWorker implements Workable,Feedable{
    void work(){};
    void eat(){};
}
RobotWorker implements Workable{
    void work(){};
}

五.依赖倒置原则(DIP):

说明:高层模块不要依赖低层模块。高层模块和低层模块应该通过抽象来互相依赖。除此之外,抽象不要依赖具体实现细节,具体实现细节依赖抽象

这里的高层模块,从代码角度来说就是调用者,底层模块就是被调用者。即调用者不要依赖于具体的实现,而应该依赖于抽象。而具体的实现与框架直接并没有直接耦合。

内容:高级模块不应依赖于低级模块,而是应该通过抽象相互依赖。此外,抽象不应该依赖于实现细节,而实现细节依赖于抽象

从代码的角度来看,这里的高级模块是调用者,低级模块是被调用者。也就是说调用者不应该依赖于具体的实现而应该依赖于抽象。框架依赖Aware接口向具体实现添加功能,具体实现通过实现接口获得功能。该实现并不直接与框架耦合。

public class EmployeeService {//反例
	private EmployeeFinder emFinder; //concrete class, not abstract.
	//Can access a SQL DB for instance
	public Employee findEmployee() {
	emFinder.findEmployee()
}
}
public class EmployeeService {//修改后
    private IEmployeeFinder emFinder
    //depends on an abstraction, no an implementation
    public Employee findEmployee() {
        emFinder.findEmployee()
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
专题一:计算机系统知识 1 1、计算机硬件基础知识: 1 1.1计算机系统结构 1 1.2 计算机中的编码: 3 1.3存储器系统 8 1.4中央处理器CPU 15 1.5 输入/输出系统 17 1.6 计算机总线结构 19 1.7 体系结构其他的知识 19 1.8 计算机的安全、可靠性评价 * 24 1.9 数学基础知识 28 1.9.1命题逻辑的基础知识 28 1.9.2 谓词逻辑、形式逻辑基础知识 31 1.9.3排列组合、概率论应用、应用统计 34 1.9.4线性规划 37 专题二:程序语言部分 39 1、程序语言知识 39 1.1 程序语言: 39 1.2 汇编语言: 42 1.3 解释程序: 42 1.4 编译程序: 43 2.重点与难点 45 2.1文法及语言形式描述: 45 2.2 词法分析 46 2.3 语法分析 47 2.4代码优化 48 专题三:操作系统知识 53 1、操作系统知识: 53 1.1基本概述 53 1.2 处理机管理 55 1.3进程概念: 55 1.4存储管理 58 1.5设备管理: 61 1.6文件和文件系统 62 1.7 作业管理与用户界面 64 1.8操作系统的结构 64 1.9常用操作系统 67 2.重点与难点: 68 2.1进程相关的概念: 68 2.2信号量处理: 69 2.3各种调度算法: 69 专题四:多媒体专题 71 1、多媒体知识: 71 1.1多媒体知识概述 71 1.2图形和图像 73 1.3音频 74 1.4视频 76 1.5数据压缩和编码技术标准 77 2 多媒体重点和难点 79 专题五:计算机网络知识 81 1、计算机网络知识 81 1.1计算机网络知识概述: 81 1.2网络协议和架构模型: 82 1.3网络操作系统: 83 1.4局域网技术 84 1.5广域网技术 85 1.6 Internet/Intranet/Extranet 86 1.7 C/S与B/S结构 87 1.8网络安全性: 88 1.9网络应用: 89 1.10网络管理 89 1.11 信息化基础知识 90 专题六: 数据库知识 99 1、数据库知识 99 1.1数据管理技术的发展 99 1.2数据模型 100 1.3数据库系统的结构 101 1.4关系模型和关系运算 101 1.5关系数据库SQL语言 104 1.6 数据库设计 106 1.7关系数据库规范化理论 106 1.8数据库保护 108 1.9数据仓库与分布式数据库 113 2.数据库重点和难点: 118 2.1 数据库管理系统(DBMS) 118 2.2 SQL语句 119 2.3 关系运算 119 2.4关系范式: 121 专题七:软件工程专题 122 1、软件工程知识 122 1.1概述 122 1.2软件分析 124 1.3软件设计 125 1.4软件测试 128 1.5软件开发工具与环境(CASE) 129 1.6软件维护和软件管理 130 1.7面向对象技术 133 1.7.1面向对象的基本概念 133 1.7.2面向对象的分析方法 135 1.7.3面向对象设计方法 136 1.8软件质量(重点) 137 1.8.1八项质量管理原则 138 1.8.2十三个步骤: 140 1.9软件配置管理 140 1.10软件过程改进 142 专题八:知识产权和标准化知识 146 1 标准化的基本知识 146 1.1标准化的基本概念 146 1.2标准化原理: 147 1.3标准的分类 148 1.4标准的代号和编号 151 1.5国际标准和国外先进标准 154 1.6标准化组织 156 1.7 ISO9000标准简介 160 1.8能力成熟度模型CMM简介 162 2 知识产权基础知识: 166 2.1知识产权介绍 166 2.2 计算机软件保护条例: 169 专题九:数据结构知识 173 1. 数据结构概述 174 2. 常用数据结构 175 2.1线性表 175 2.2 栈 178 2.3队列 181 2.4 串 184 2.5 数组 185 2.6 树 189 2.6.1概述 189 2.6.2二叉树 190 2.7图 192 3. 数据结构相关算法 195 3.1排序算法 195 3.2查找算法 211 4 重点、难点解析 212 专题十:算法分析与设计 214 1.常用的算法设计方法: 214 1.1 迭代法: 214 1.2 穷举搜索法: 215 1.3 递推法: 217 1.4 递归法 218 1.5 贪婪法 224 1.6 分治法 227 1.7 动态规划法 229 1.8 回溯法 234 1.9 分支定界法: 235 2.几个重要的算法程序 235 2.1 堆排序 235 2.2 归并排序 237 专题十一: 系统工程知识 239 1.系统与系统工程: 239 1.1 系统的概念: 239 1.2系统的分类 239 1.3系统的特性 239 1.4系统与环境 240 1.5系统工程与系统方法 240 1.6信息系统工程 240 2.系统分析基础知识 241 2.1系统分析的目的和任务 241 2.2结构化分析方法 241 2.3统一建模语言(UML) 243 2.4系统规格说明书 245 3.系统设计基础知识 245 3.1系统设计的目的和任务 245 3.2结构化设计方法和工具 245 3.3系统总体结构设计 245 3.4系统详细设计 246 3.5系统设计说明书 247 4.系统实施知识 248 4.1系统实施的主要任务 248 4.2结构化程序设计、面向对象程序设计、可视化程序设计 248 4.3系统测试的目的、类型,系统测试方法 248 4.4系统转换基础知识 249 5.系统运行和维护知识 249 5.1系统运行管理基础知识 249 5.2系统维护基础知识 250 5.3系统评价基础知识 250 专题十二: JAVA程序设计语言 251 1 Java和面向对象概述 255 2 Java概述 256 2.1 安装并配置Java 平台 257 2.1.1 Java平台概述 257 2.1.2 Java平台的安装 257 2.2 第一个Java Application程序 257 2.2.1 编辑源程序 257 2.2.2 字节码的编译生成 259 2.2.3 字节码的解释与运行 259 2.3 使用集成开发环境 259 3 Java语言基础 260 3.1 Java程序的构成 260 3.2关键字、标识符、数据类型、常量与变量 261 3.2.1 关键字 261 3.2.2 标识符 261 3.2.3 数据类型 261 3.2.4 常量与变量 262 3.3 运算符 263 3.3.1 算术运算 264 3.3.2 关系运算 264 3.3.3 位运算 264 3.3.4 类型转换 265 3.3.5 其他运算符 266 3.3.6 运算符的优先级与结合性 267 3.4 流程控制语句 267 3.4.1 结构化程序设计的三种基本流程 267 3.4.2 选择结构 267 3.4.3 循环结构 268 3.4.4 跳转语句 269 4 类和对象 270 5 继承 272 6 字符、字符串、数组 274 6.1 字符 275 6.1.1 Character类的构造函数 275 6.1.2 Character类提供的常用方法 275 6.2 字符串 275 6.2.1 字符串常量与String类 276 6.2.2 字符串变量与StringBuffer类 278 6.3 数组 279 6.3.1 数组的创建和初始化 279 6.3.2 数组的数组 280 6.3.3 复制数组 280 6.3.4 数组类Arrays 280 6.3.5 命令行参数 281 7 图形用户界面的设计与实现 281 7.1图形用户界面概述 282 7.2 图形用户界面 282 8 Applet 286 8.1 Applet的基本工作原理 286 8.2 Applet类与JApplet类 287 8.2.2 Applet与Application的区别 288 8.3 Applet安全基础 288 8.4 向Applet传递参数 289 8.5 Application与Applet组合 289 8.6 Applet与JAR文件 290 8.6.1 JAR文件概述 290 8.6.2 jar命令 290 8.6.3 JAR缓存 290 9 Java高级编程 291 9.1异常处理 291 9.2 Java多线程机制 295 9.3 流式输入输出与文件处理 295 9.3.1 Java输入输出类库继承关系 296 9.3.2基于标准输入输出的IO操作 296 9.3.3文件读写及随机访问 297 9.3.4Java的文件管理 297 9.4 Java网络通信 297 9.4.1网络基础知识及Java网络模型 298 9.4.2无连接的数据报 298 9.4.3 Java访问网络资源 298

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值