将类的功能层次结构与实现层次结构分离
1.基本介绍
将类的功能层次结构和类的实现层次结构连接起来。
类的功能层次结构:
希望增加新的功能,例如有一个Something类,想在其中增加新的功能时,一般会写一个子类,这就构成了类层次结构.为了增加功能而产生的层次结构。
当增加新的功能时,从各个层次中找出符合自己需求的类,以它为父类编写子类,并在子类中增加新的功能。
- 父类具有基本功能
- 子类中增加新的功能
ps: 类的层次结构关系不应该过深。
类的实现层次结构:
抽象类或者接口定义方法,子类去具体实现这些方法,这种层次结构并非用于增加接口.
- 父类通过声明抽象方法定义方法.
- 子类通过具体实现方法实现接口.
类的层级结构的混杂与分离:
当类的层次结构位于一层时,功能层次结构与实现层次结构混在在同一个机构层次中,很容易使类的结构层次变的复杂,也难以透彻的理解类的层次结构。因此,要将类的功能层次与类的实现层次分离开。
2.具体实现
类的一览表:
程序类图:
Display类
位于类的功能层次结构最上层。
imp字段中保存的是实现了Display类的具体功能实例,此字段则为类俩个结构层次的桥梁。
/**
* @author Jay
* @date 2019/6/4 22:59
* @description
*/
public class Display {
/**
* 桥梁作用
*/
private DisplayImpl imp;
public Display(DisplayImpl imp) {
super();
this.imp = imp;
}
public void open() {
imp.rawOpen();
}
public void print() {
imp.rawPrint();
}
public void close() {
imp.rawClose();
}
public final void display() {
open();
print();
close();
}
}
CountDisplay类
继承自Display,在其基础上增加了新的功能,类的功能结构层次.
/**
* @author Jay
* @date 2019/6/4 23:01
* @description
*/
public class CountDisplay extends Display {
public CountDisplay(DisplayImpl imp) {
super(imp);
}
/**
* 增加的功能
*
* @param times
*/
public void multiDisplay(int times) {
open();
for (int i = 0; i < times; i++) {
print();
}
close();
}
}
DisplayImpl类
类的实现层次结构最上层。
/**
* @author Jay
* @date 2019/6/4 23:00
* @description
*/
public abstract class DisplayImpl {
public abstract void rawOpen();
public abstract void rawPrint();
public abstract void rawClose();
}
StringDisplayImpl类
/**
* @author Jay
* @date 2019/6/4 23:02
* @description 具体实现其中的方法.
*/
public class StringDisplayImp extends DisplayImpl {
private String string;
private int width;
public StringDisplayImp(String string) {
super();
this.string = string;
this.width = string.getBytes().length;
}
@Override
public void rawOpen() {
printLine();
}
@Override
public void rawPrint() {
System.out.println("|" + string + "|");
}
@Override
public void rawClose() {
printLine();
}
private void printLine() {
System.out.print("+");
for (int i = 0; i < width; i++) {
System.out.print("-");
}
System.out.println("+");
}
}
Main:测试类
/**
* @author Jay
* @date 2019/6/4 23:03
* @description
*/
public class Main {
public static void main(String[] args) {
//接收类型为接口类型,其实现类全部可以使用
Display d1 = new Display(new StringDisplayImp("hello china"));
//父类功能
d1.display();
System.out.println("************************");
//子类掉用的父类功能
Display d2 = new CountDisplay(new StringDisplayImp("hello world"));
d2.display();
System.out.println("************************");
//子类独有功能
CountDisplay d3 = new CountDisplay(new StringDisplayImp("hello miss"));
d3.multiDisplay(2);
}
}
3.角色分析
Abstraction(抽象化)
位于类的功能层次结构最上层使用Implementor角色的方法定义了基本的功能,保存了Implementor的实例。
RefinedAbstraction(改善后的抽象化)
在Abstraction角色的基础上增加了新功能的角色.
Implementor(实现者)
位于类的实现层次结构最上层,定义了实现Abstraction角色的接口方法.
ConcreteImplementor(具体实现者)
具体实现了父类中定义的抽象方法.
4.思考
分开后容易扩展
将类的功能层次结构与类的实现层级结构分开,有利于独立的对他们进行扩展,要增加功能时,只需在类功能一侧增加功能,不需要对另一侧进行修改,增加的功能都可以被所有的实现所使用.
继承是强关联,委托是弱关联
使用继承容易扩展类,也形成了一种强关联关系,只要不修改代码,变无法改变这种关系,想改变类之间的关系,就可以用委托来代替继承.