一、接口隔离原则
我们先来看一个例子:
动物行为
// 动物行为
public interface Animal {
// 吃
public void eat();
// 游泳
public void swim();
// 飞
public void fly();
}
老虎Tiger
// 老虎
public class Tiger implements Animal {
@Override
public void eat() {
System.out.println("老虎在吃鸡肉.....");
}
@Override
public void swim() {
System.out.println("老虎在游泳.....");
}
@Override
public void fly() {
System.out.println("老虎不能飞.....");
}
}
小鸟Brid
// 小鸟
public class Brid implements Animal {
@Override
public void eat() {
System.out.println("小鸟在吃虫子.....");
}
@Override
public void swim() {
System.out.println("小鸟不会游泳.....");
}
@Override
public void fly() {
System.out.println("小鸟正在飞.....");
}
}
// 游泳
public interface ISwim {
public void swim();
}
// 吃
public interface IEat {
public void eat();
}
// 飞
public interface IFly {
public void fly();
}
小鸟Bird
// 小鸟
public class Brid implements IEat,IFly {
@Override
public void eat() {
System.out.println("小鸟在吃虫子.....");
}
@Override
public void fly() {
System.out.println("小鸟正在飞.....");
}
}
老虎Tiger
// 老虎
public class Tiger implements IEat,ISwim {
@Override
public void eat() {
System.out.println("老虎在吃鸡肉.....");
}
@Override
public void swim() {
System.out.println("老虎在游泳.....");
}
}
二、迪米特法则
迪米特法则认为,一个对象或方法,它只能够调用以下对象:
- 该对象本身
- 作为参数传进来的对象
- 在方法内创建的对象
我们先来模拟一个超市购物的场景:顾客Customer
到收银台结账,收银员PaperBoy
负责收钱。
顾客的钱包Wallet
// 钱包
public class Wallet {
// 钱包里装的钱
private Float value;
// 构造器
public Wallet(Float value) {
this.value = value;
}
// 获得钱包里的钱的金额
public Float getMoney(){
return this.value;
}
// 付账时 减钱
public void reduceMoney(Float money){
this.value -= money;
}
}
顾客Customer
// 顾客
public class Customer {
private Wallet wallet = new Wallet(50f);
public Wallet getWallet() {
return wallet;
}
}
收银员PaperBoy
// 收银员
public class PaperBoy {
// 收银员收钱
public void charge(Customer customer,Float money){
Wallet wallet = customer.getWallet();
if (wallet.getMoney() >= money){
System.out.println("顾客付账:" + money +"元");
// 减去 应付的钱
wallet.reduceMoney(money);
System.out.println("钱包里还剩:"+wallet.getMoney()+"元");
} else {
System.out.println("钱包里的金额不够......");
}
}
}
测试、运行
// 测试
public static void main(String[] args) {
PaperBoy paperBoy = new PaperBoy();
Customer customer = new Customer();
paperBoy.charge(customer,20f);
}
从测试代码和运行的结果来看,好像并没有什么问题。让我们来看一下类图:
从类图中我们发现:PaperBoy
类与Wallet
类有着千丝万缕的关系,顾客(Customer
)的钱包(Wallet
)好像并不是自己来控制的,而是由收银员(PaperBoy
)来决定的,就连钱包(Wallet
)里面的钱够不够也是由收银员(PaperBoy
)来判断的;相当于顾客(Customer
)将自己的钱包(Wallet
)暴露给了收银(PaperBoy
),这样来看,问题就很严重了,顾客(Customer
)的隐私受到了侵犯,说大点就是民事纠纷,是可以上法庭的,可以通过法律追究责任的。所以我们思考良久,将上述代码改成下面这般:
钱包Wallet
类不变,顾客Customer
去掉给出钱包的getWallet()
方法,增加付钱的pay()
方法:
// 顾客
public class Customer {
private Wallet wallet = new Wallet(50f);
// 顾客自己付钱
public void pay(Float money){
if (wallet.getMoney() >= money){
System.out.println("顾客付账:" + money +"元");
// 减去 应付的钱
wallet.reduceMoney(money);
System.out.println("钱包里还剩:"+wallet.getMoney()+"元");
} else {
System.out.println("钱包里的金额不够......");
}
}
}
收银员PaperBoy
类中的charge()
方法中的代码删除原有的逻辑,改为调用顾客Customer
类中的付钱pay()
方法:
// 收银员
public class PaperBoy {
// 收银员收钱
public void charge(Customer customer,Float money){
customer.pay(money);
}
}
测试代码不变,我们再来看看类图:
从类的结构图来看:收银员PaperBoy
只和顾客Customer
有联系,钱包Wallet
只和顾客Customer
有联系。再此情况下,如果把钱包Wallet
也当作一个人来看的话,这个就是如下的关系:
- 顾客
Customer
和钱包Wallet
是朋友 - 顾客
Customer
和收银员PaperBoy
是朋友 - 钱包
Wallet
和收银员PaperBoy
是陌生人
这个就符合我们所说的迪米特法则中的核心:只和朋友交流,不和陌生人说话。