1、定义:将抽象部分和它的实现部分分离,使它们都可以独立的变化。
这个定义真的很拗口,然后GoF的定义,我也是读了好几遍,还是有点蒙圈。还好书里有一个比较通俗的解释:实现系统可能会有多角度分类,每一种分类都有可能变化,那么就把这种多角度分离出来让他们独立变化,减少它们之间的耦合。
举个例子:
手机的实现可以通过先按照品牌分类,然后在品牌下再按照功能分类;
也可以先按照功能分类,然后每个功能下面再按照手机品牌分类;
因为手机品牌和有哪些功能都是经常变化的东西。所以在实现一个手机时,将手机品牌和手机功能独立实现,而不是通过继承实现强耦合。这样在增加一个手机品牌or增加一个手机功能时,只需要添加一个类即可,曾经的代码并不需要改动,符合开放-封闭原则;且实现了手机品牌和手机功能的解耦。
关于手机的例子,通过继承实现的两种方式如下图:
2、优势:
2.1、code上面的表现:
(1)保持每个类被封装。
(2)每个类被单独使用在单个任务上。
2.2、使用后结果上的表现:
这样会使得类和类继承层次保持较小规模,并且不太可能增长为不可控制的庞然大物。
3、UML图:
4、例子:
4.1、场景:手机分品牌和功能,且品牌和功能经常发生变化。每个手机都有自己的品牌和功能。如何实现多个手机的构建过程?
4.2、UML图:
4.3、code:
(1)代码结构图
(2)code
package designmodel.chapter22;
/**
* @Author: cxh
* @CreateTime: 18/1/25 22:45
* @ProjectName: JavaBaseTest
*/
public class BrandA1 extends PhoneBrand {
@Override
public void run() {
super.softWare.run();
}
}
package designmodel.chapter22;
/**
* @Author: cxh
* @CreateTime: 18/1/25 22:47
* @ProjectName: JavaBaseTest
*/
public class BrandA2 extends PhoneBrand {
@Override
public void run() {
super.softWare.run();
}
}
package designmodel.chapter22;
/**
* @Author: cxh
* @CreateTime: 18/1/25 22:46
* @ProjectName: JavaBaseTest
*/
public class BrandB1 extends PhoneBrand {
@Override
public void run() {
super.softWare.run();
}
}
package designmodel.chapter22;
/**
* @Author: cxh
* @CreateTime: 18/1/25 22:51
* @ProjectName: JavaBaseTest
* 测试类
*/
public class Client {
public static void main(String[] args) {
PhoneBrand brand;
//手机品牌A1
System.out.println("----手机品牌A1----");
brand=new BrandA1();
brand.setSoftWare(new SoftWareV1());
brand.run();
brand.setSoftWare(new SoftWareV2());
brand.run();
brand.setSoftWare(new SoftWareV3());
brand.run();
//手机品牌A2
System.out.println("----手机品牌A2----");
brand=new BrandA2();
brand.setSoftWare(new SoftWareV1());
brand.run();
brand.setSoftWare(new SoftWareV2());
brand.run();
brand.setSoftWare(new SoftWareV3());
brand.run();
//手机品牌A3
System.out.println("----手机品牌A3----");
brand=new BrandB1();
brand.setSoftWare(new SoftWareV1());
brand.run();
brand.setSoftWare(new SoftWareV2());
brand.run();
brand.setSoftWare(new SoftWareV3());
brand.run();
}
}
package designmodel.chapter22;
/**
* @Author: cxh
* @CreateTime: 18/1/25 22:40
* @ProjectName: JavaBaseTest
*/
public abstract class PhoneBrand {
//持有软件的引用
protected PhoneSoftWare softWare;
public void setSoftWare(PhoneSoftWare softWare) {
this.softWare = softWare;
}
//调用软件功能方法
public abstract void run();
}
package designmodel.chapter22;
/**
* @Author: cxh
* @CreateTime: 18/1/25 22:39
* @ProjectName: JavaBaseTest
*/
public abstract class PhoneSoftWare {
abstract void run();
}
package designmodel.chapter22;
/**
* @Author: cxh
* @CreateTime: 18/1/25 22:48
* @ProjectName: JavaBaseTest
*/
public class SoftWareV1 extends PhoneSoftWare {
@Override
void run() {
System.out.println("手机通信录功能运行");
}
}
package designmodel.chapter22;
/**
* @Author: cxh
* @CreateTime: 18/1/25 22:49
* @ProjectName: JavaBaseTest
*/
public class SoftWareV2 extends PhoneSoftWare{
@Override
void run() {
System.out.println("手机游戏功能运行");
}
}
package designmodel.chapter22;
/**
* @Author: cxh
* @CreateTime: 18/1/25 22:50
* @ProjectName: JavaBaseTest
*/
public class SoftWareV3 extends PhoneSoftWare {
@Override
void run() {
System.out.println("手机拍照功能运行");
}
}