第九章面向复用的软件构造技术
复用的级别
Source code level: methods, statements, etc
Module level: class and interface //可在java中使用类继承或者类委托的方式
Library level: API – Java Library, .jar
Architecture level: framework 框架
代码复用的种类:白盒复用和黑盒复用(顾名思义)
System-level reuse: Framework
框架:一组具体类、抽象类、及其之间的连接关系
开发者根据framework的规约,填充自己的代码进去,形成完整系统
White-box and Black-Box Frameworks
Whitebox frameworks 白盒框架,通过代码层面的继承进行框架扩展
Blackbox frameworks 黑盒框架,通过实现特定接口/delegation进行框架扩展
设计可复用的类
Liskov替换原则
定义:如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型S是类型T的子类型。
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法;
- 子类中可以增加自己特有的方法。
协变:从宽泛到具体 ,逆变:从具体到宽泛
在java中arrays是协变的:也就是可以实现如下的结构:
Number[] numbers = new Number[2];
numbers[0] = new Integer(10);
numbers[1] = new Double(3.14);
Integer[] myInts = {1,2,3,4};
Number[] myNumber = myInts;
myNumber[0] = 3.14; //run-time error!
在java中泛型不是协变的,下面的代码将会发生Compile error
List<Integer> myInts = new ArrayList<>();
myInts.add(1);
myInts.add(2);
List<Number> myNums = myInts;
原因是:如果泛型类型中的类型参数是无限制的,将被对象类型参数所替 换因此,生成的字节码只包含普通类、接口和方法
不过可以通过使用通配符?来实现想要的效果
List<Integer> myInts = new ArrayList<>();
myInts.add(1);
myInts.add(2);
List<? extends Number> myNums = myInts;
继承和委托
Composite Reuse Principle (CRP) 复合重用原则
类通过“组合”实现多态和复用(通过引入其他类的实例来实现功能)而不是通过基类或父类。
热知识:java的接口可以多继承(