复用软件评价
一.什么是软件复用
1.面向复用性编程:开发可以服用的软件
2.基于复用编程:利用可复用的软件开发
开发可复用的软件会导致:开发成本高,泛用性强,性能好。
度量可复用性
1.复用的频繁程度
2.复用的代价程度
二.复用层面
1.源码级复用:对源代码进行复制修改。
2.模块层面复用:对已有的类进行复用。
继承与委托技术,扩展现有类
3.库层面的复用:API复用
库:提供一组类与方法
4.框架层面复用
分类:黑盒,白盒复用。
对于库复用,用户代码主体。
对于框架复用:框架主体
三.可复用的外部表示
1.类型可变:泛型的复用性好于非泛型
2.实现可变:rep可以变化
3.共性抽取
4.功能分组
5.表示独立
开发可复用软件的技术
设计可复用的类:
1.继承重写 2.泛型参数 3.委托4.重载
一.LSP(里氏替换原则)
里氏替换原则是重要的设计模式原则
概括地说:客户端允许以统一方式处理子类型
继承的目的就在于能够统一处理子类型,要求子类型不仅与基类有逻辑上的is-a关系,也应该有行为的一致性。否则我们的继承是没有意义的。
子类型在保证
1.必须重写抽象空方法,不能删除方法。
2.重写的返回值,异常要求协变
3.重写参数要求逆变
4.子类型的前置弱于基类
5.子类型的后置强于基类
6.更强不变量
LSP保障——强行为子类型
前置不能强化,后置不能弱化,不变量要保障,返回值,异常协变,参数逆变
Java不支持逆变
二.泛型与数组的子类型行为
数组行为
数组是支持协变的,Number[] a= new Integer[3]();
在编译时可以通过,因为数组运行时保留类型,可以动态知道实际类型。a中不能添加Double 运行时出错。
泛型行为
对于泛型而言,泛型实际上进行类型擦除,不会有类型保留,所以如果像这样呀List a = new ArrayList();
是不被允许的,如果允许,那么a中添加元素时,是不知道添加的是否合法的。
所以泛型参数子类型,不能代表泛型子类型
泛型通配符
泛型中支持为泛型创建使用通配符。
<?> 支持所有类型,与相同<?extends A> 参数是A的子类型,这个泛型的子类型是所有A子类型的泛型
<? super A> 参数是A的父类型,这个泛型的子类型是A所有父类型的泛型。 容器中的通配符是让人迷惑的。 我们不能实例化ArrayList<? extends A> 但我们可以创建一个引用 s,并把A子类型泛型赋给他。 此时s是不能set 的,因为他的泛型参数是所有A的子类型,但实际是明确的一个未知子类型。set无法保证放入的数据是 A1类型的。 但是可以get,所有数据都可以安全转型到A。