1、设计可复用的类

1.1 行为子类型和LSP

子类型:

​相比于父类型,要有相同或更强的ADT(前置条件变弱后置条件变强更强的不变量);

​在java中表现为:子类型可以增加方法;子类型中重写的方法必须返回相同或子类型的返回值(协变);子类型中重写的方法必须接受相同类型的参数(逆变);子类型重写的方法不能抛出额外异常。

例子:
​假如一个长方形类、一个正方形类,然后正方形类继承长方形类。长方形有一个方法setWidth:改变某条边的长度。这时正方形类就无法继承这个方法,因为会破坏规约。正方形类和长方形类不应该是继承,而应该是委托的关系。

LSP:

协变:

​ 子类型中重写的方法的返回值是父类中方法返回值的子类,子类的异常也应该是父类异常的子类。这种同向的变化就叫协变。

​ 协变还有一层含义就是子类型的实例可以被赋给父类型

逆变:

​ 子类型中重写的方法的参数是父类中方法参数的父类。这种逆向的变化就叫逆变。java中不支持逆变,当作重载处理(Overload)。

​ 数组是协变的。泛型不协变,泛型只存在于编译阶段,之后会被擦除,例如:List和List是相同的,类型擦除后都是List。

泛型擦除:

​ 对于泛型使用类型查询:

​ instance of一个泛型类会编译不通过,getclass可运行,但运行时类型被擦除,故Pair<String>和Pair<Employee>是相等的。

​泛型不存在协变,故不可以将一个泛型类赋值给另一个泛型类,这里的List<a>与List<b>毫无关系,故不可以这样赋值:

​要写泛型方法可使用通配符:

​ 下限通配符、上限通配符, 有了通配符,泛型就有子类的概念了:

​ PECS:producer要用super,consumer要用extend。

1.2、委托、组合

​ 如果一个类继承另一个类,很可能继承下来很多不可用的方法,需要重写这些方法为空。好的做法:委托。可以避免大量不需要的方法。

​ ADT的比较的两种实现:

​ 1、实现一个比较器,然后将比较任务委托给这个比较器Comparator;

​ 注意comparator中compare函数的逻辑:返回1的时候将两个对象互换,所以下面这个是升序:

​ 2、这个ADT实现Comparable接口,在ADT中实现compareTo函数,这样就把比较封装在了ADT内部,而不用额外实现一个比较器类,但这不是委托。

显式委托:通过传入对象,然后调用这个对象的方法,比如说比较器:

隐式委托:类中声明一个成员变量,然后类的方法调用这个成员变量的方法:

B隐式委托A,就是指B中声明一个A类型的成员变量a,然后B中方法的实现都依托于这个a。例如lab2中:

组合:问题在于对象层面而不在于类的层面,一个类的不同对象可能有不同的行为。

​ 比如说开发一个动物类ADT,行为有叫和飞,有十余种飞和叫的方式,好的实现:接口之间通过extends实现拓展,比如说鸭子会叫又会飞,就可以extends Flyable、Quackable接口,其中Flyable、Quackable接口又各有十余种实现:

​ 然后鸭子类对fly、quack的实现可以委托给Flyable和Quackable两个接口:

​ 客户端给一个对象分配它的行为方式,这样同样是duck类,就可以有不同的行为方式:

​ 组合的总体形式:

委托的种类:

​ (1)依赖Dependency

​ 这是临时性的委托,通过方法传参建立局部的联系,被委托的对象也不是这个类的成员变量:

​ (2)association

​ 这是永久性的委托,一个类将要委托的对象作为自己的成员变量,其有两种形态,分别是composition和aggregation。

​ (3.1)组合composition

​ 这是更强的association,但难以变化,就是初始化的时候对成员变量进行赋值,是死的,没办法变化。

​ (3.2)聚合aggregation

​ 这是更弱的association,可以动态变化,即有专门的方法对其成员变量进行赋值。

2、系统层面的可复用——库和框架

库的复用:我们写的代码调用库;

框架的复用:我们写的代码填充框架,框架调用我们写的代码。

白盒框架:

​ 框架中有一些未完成的方法、空白,子类通过继承和重写方法完成对框架的填充、子类有主方法但调用是由框架调用。例如模板模式就是白盒框架。客户端写main。一次只能进行一次扩展,开发者框架。

​ 一个抽象类白盒框架:

黑盒框架:

​ 看不到代码,框架只提供一系列接口,通过plugin实现接口来实现框架的填充,相当于是通过委托来实现,由框架调用。框架写main。一次可进行多次扩展,用户框架。

​ 这个黑盒框架有一个成员变量作为接口,外部plugin实现接口:

两个框架的工作流程:

设计框架的指导原则:

​1、确定该框架的领域;

​2、找出通用的部分,在框架中实现;

​3、可变的部分留给外部去实现;

​4、接口——抽象类——具体类:由抽象到具体,通用的向上放。

使用库和框架的投资回报曲线:

Collections介绍:
主要就是有四个接口:list、set、map、queue,实战都接触了,不记了。
迭代器的删除是安全的,其他对集合的删除会造成索引的混乱。
迭代器在4-3有详细介绍。

4-2 面向复用的软件构造技术相关推荐

  1. 软件构造学习笔记(九)面向复用的软件构造技术

    目录链接 Part I What is Software Reuse? Part II How to measure "reusability"? Part III Levels ...

  2. 软件构造(九) 面向复用的软件构造技术

    1.什么是软件复用 软件重用是使用现有软件组件实现或更新软件系统的过程. 软件复用有两方面: 面向复用编程:开发出可复用的软件 基于复用编程:利用已有的可复用软件搭建应用系统 为什么复用: 降低成本和 ...

  3. 面向复用的软件构造技术知识点总结与思考

    一.复用 1.复用种类: 白盒复用:源代码可见,复制已有代码到正在开发的系统,进行修改和扩展 黑盒复用:源代码不可见,不能修改,只能通过API接口来使用 1)源码级别复用 2)模块级别复用:类,接口 ...

  4. 2022哈工大软件构造课程总结与经验分享(复习指导)

    一.软构1-3讲 1.软件构造的多维度视图和质量目标 2.软件测试与测试优先的编程 3.软件构造过程与配置管理 二.软构4-8讲 4.数据类型与类型检验 5.设计规约 6.抽象数据类型 (ADT) 7 ...

  5. 2021哈工大软件构造期末考点复习笔记

    第一节 多维视图和质量目标 软件构造多维度视图 红色标注为重点(考试会考选择题) Moment 特定时刻的软件形态 Period 软件形态随时间的变化 AST (Abstract Syntax Tre ...

  6. 2021-06-29 Views and Quality Objectives of Software Construction 软件构造的多维度视图和质量目标

    第一章:Views and Quality Objectives of Software Construction 软件构造的多维度视图和质量目标 目标 1.从三个维度看软件系统的构成 2.用什么样的 ...

  7. [HITSC]哈工大2020春软件构造Lab3实验报告

    Github地址 1 实验目标概述 本次实验覆盖课程第 3.4.5 章的内容,目标是编写具有可复用性和可维护 性的软件,主要使用以下软件构造技术: 子类型.泛型.多态.重写.重载 继承.代理.组合 常 ...

  8. HIT 软件构造 lab3实验报告

    2020年春季学期 计算机学院<软件构造>课程 Lab 3实验报告 姓名 赵旭东 学号 1180300223 班号 1803002 电子邮件 1264887178@qq.com 手机号码 ...

  9. 2022 - 软件构造复习

    软件生命周期 一个软件产品或软件系统经历孕育.诞生.成长.成熟.衰亡等阶段,一般称为软件生存周期(软件生命周期). 根据软件所处的状态和特征,划分软件生存周期. 需求定义.软件设计.软件实现.软件维护 ...

最新文章

  1. 电脑cpu排名_可能是最详细的小白【笔记本电脑】选购攻略(附热门机型推荐)...
  2. BOOST_VMD_ASSERT_IS_LIST相关的测试程序
  3. Linux下Anaconda3安装及使用教程
  4. solr后台界面介绍——(十一)
  5. linux shell之paste合并文件和找到匹配的文件里面替换内容(find和-exec或xargs组合)
  6. android生命周期_Android开发 View的生命周期结合代码详解
  7. eigen 列向量转矩阵_快速入门矩阵运算——开源库Eigen
  8. Bootstrap3 按钮组插件
  9. Linux 启动文件、设置环境变量的位置
  10. mysql 遍历二叉树_数据结构-二叉树遍历
  11. SSCI写作--期刊检索和基本介绍
  12. C语言编程常用知识点概论——第一章基本数据类型、运算符
  13. 注册登录页面模板 农业集团 金星农业
  14. 谷歌浏览器翻译插件 划词翻译
  15. 印刷电路板丝网设计的十大技巧
  16. Livid : 在 26 岁时写给 18 岁的自己
  17. python爬取pexels网站图片
  18. 三种页面置换算法(详解)
  19. PHP socket 连接 Socket server
  20. 2019 让自己变的更加优秀(文末新年福利)

热门文章

  1. 2015年 StoiGdoi 反思总结与未来计划
  2. 【转载】linux进程控制-exec系列 exec系统调用
  3. 分布式id-数据库实现
  4. XPath: A Syntax for Describing Needles and Haystacks(Chapter 3 of XSLT 2nd Edition)
  5. BUAAOO电梯作业总结
  6. 学习node.js的一些笔记
  7. Intellij IDEA中如何给main方法赋args
  8. 结队编程1-四则运算(107、120)
  9. Android学习之Intent使用
  10. 天外印刷的计件工资项目结束了