我们下面帮刘邦实现其管理系统。我们将用这个例子讲解面向对象编程的核心:
A 面向接口编程。
B合成复用原则。
好处:
为何“要尽量使用合成和聚合,尽量不要使用继承”呢?这是因为:第一,继承复用破坏包装,它把超类的实现细节直接暴露给了子类,这违背了信息隐藏的原则;第二:如果超类发生了改变,那么子类也要发生相应的改变,这就直接导致了类与类之间的高耦合,不利于类的扩展、复用、维护等,也带来了系统僵硬和脆弱的设计。而是用合成和聚合的时候新对象和已有对象的交互往往是通过接口或者抽象类进行的,就可以很好的避免上面的不足,而且这也可以让每一个新的类专注于实现自己的任务,符合单一职责原则。
下面是实现:
package com.diermeng.designPattern.CARP;
/*
* 大臣的接口
*/
public interface Minister {
/*
* 大臣能够执行的动作
*/
public void duty();
}
士兵的接口
package com.diermeng.designPattern.CARP;
/*
* 士兵的接口
*/
public interface Soldier {
/*
* 士兵能够执行的动作
*/
public void duty();
}
韩信对大臣接口的实现
package com.diermeng.designPattern.CARP.impl;
import com.diermeng.designPattern.CARP.Minister;
import com.diermeng.designPattern.CARP.Soldier;
/*
* 韩信对大臣接口的实现
*/
public class Hanxin implements Minister {
//对士兵的聚合关系
Soldier[] soldiers;
/*
* 无参构造方法
*/
public Hanxin() {}
/*
* 有士兵参数的构造方法
*/
public Hanxin(Soldier[] soldiers) {
super();
this.soldiers = soldiers;
}
/*
* 获取士兵的集合
*/
public Soldier[] getSoldiers() {
return soldiers;
}
/*
* 设置士兵的集合
*/
public void setSoldiers(Soldier[] soldiers) {
this.soldiers = soldiers;
}
/*
* 韩信的职能
* @see com.diermeng.designPattern.CARP.Minister#duty()
*/
public void duty() {
System.out.println("我是刘邦的大臣,永远忠实于刘邦");
}
}
士兵A对士兵接口的实现
package com.diermeng.designPattern.CARP.impl;
import com.diermeng.designPattern.CARP.Soldier;
/*
* 士兵A
*/
public class SoldierA implements Soldier {
/*
* 士兵A的职责
* @see com.diermeng.designPattern.CARP.Soldier#duty()
*/
public void duty() {
System.out.println("我是韩信的士兵A");
}
}
士兵B对士兵接口的实现
package com.diermeng.designPattern.CARP.impl;
import com.diermeng.designPattern.CARP.Soldier;
/*
* 士兵B
*/
public class SoldierB implements Soldier {
/*
* 士兵B的职责
* @see com.diermeng.designPattern.CARP.Soldier#duty()
*/
public void duty() {
System.out.println("我是韩信的士兵B");
}
}
刘邦类
package com.diermeng.designPattern.CARP.impl;
import com.diermeng.designPattern.CARP.Minister;
/*
* 刘邦类
*/
public class Liubang {
//拥有大臣
Minister[] minister;
/*
* 无参构造方法
*/
public Liubang() {}
/*
* 把大臣的数组作为参数传入构造方法
*/
public Liubang(Minister[] minister) {
super();
this.minister = minister;
}
/*
* 获取大臣的集合
*/
public Minister[] getMinister() {
return minister;
}
/*
* 设置大臣的集合
*/
public void setMinister(Minister[] minister) {
this.minister = minister;
}
/*
* 刘邦的职能
*/
public void duty()
{
System.out.println("我是皇帝,普天之下,莫非王土;四海之内,莫非王臣");
}
}
建立一个测试类,代码如下:
package com.diermeng.designPattern.CARP.client;
import com.diermeng.designPattern.CARP.Minister;
import com.diermeng.designPattern.CARP.Soldier;
import com.diermeng.designPattern.CARP.impl.Hanxin;
import com.diermeng.designPattern.CARP.impl.Liubang;
import com.diermeng.designPattern.CARP.impl.SoldierA;
import com.diermeng.designPattern.CARP.impl.SoldierB;
/*
* 测试类的客户端
*/
public class CARPClient {
public static void main(String[] args)
{
//声明并实例化士兵A
Soldier soldierA = new SoldierA();
//声明并实例化士兵B
Soldier soldierB = new SoldierB();
//构造士兵数组
Soldier[] soldiers = {soldierA,soldierB};
//声明并实例化韩信,同时传入士兵数组
Minister hanxin = new Hanxin(soldiers);
//构造大臣数组
Minister[] minister = {hanxin};
//声明并实例化刘邦,同时传入大臣数组
Liubang liubang = new Liubang(minister);
liubang.duty();
//循环输出大臣
for(Minister aminister:liubang.getMinister()){
aminister.duty();
}
}
}
程序运行结果如下:
我是皇帝,普天之下,莫非王土;四海之内,莫非王臣
我是刘邦的大臣,永远忠实于刘邦
点评: 其实这个刘邦类也可以以接口的形式出现,如果这样的话,整个系统就可以是帝王管理系统,这样的话,这个帝王就可以曹操,也可以是刘备。非常完美的面向接口编程的实践。 同时这个系统很好的使用了
合成聚合的原则。各个模块如大臣,士兵模块都可以各司其责,同样实现了单一职能原则。