1700453550
//通话
1700453551
1700453552
public void chat();
1700453553
1700453554
}
1700453555
1700453556
(3)合并实现
1700453557
1700453558
接口定义了两个职责,难道实现类就一定要分别实现这两个接口吗?这样做确实完全满足了单一职责原则的要求:每个接口和类职责分明,结构清晰,但是我相信读者在设计的时候肯定不会采用这种方式,因为一个电话类要把ConnectionManager和DataTransfer的实现类组合起来才能使用。组合是一种强耦合关系,你和我都有共同的生命期,这样的强耦合关系还不如使用接口实现的方式呢!而且这还增加了类的复杂性,多出了两个类。
1700453559
1700453560
通常的做法是一个实现类实现多个职责,也就是实现多个接口,代码如下:
1700453561
1700453562
//电话
1700453563
1700453564
class Phone implements Connection, Transfer{
1700453565
1700453566
//实现各个接口
1700453567
1700453568
}
1700453569
1700453570
这样的设计才是完美的,一个类实现了两个接口,把两个职责融合在一个类中。你会觉得这个Phone有两个原因引起了变化,是的,但是别忘记了我们是面向接口编程的,我们对外公布的是接口而不是实现类。而且,如果真要实现类的单一职责,就必须使用上面的组合模式,这会引起类间的耦合过重、类的数量增加等问题,人为地增加了设计的复杂性。
1700453571
1700453572
对于单一职责原则,我建议接口一定要做到职责单一,类的设计尽量做到只有一个原因引起变化。
1700453573
1700453574
注意 接口职责一定要单一,实现类职责尽量单一。
1700453575
1700453576
1700453577
1700453578
1700453580
编写高质量代码:改善Java程序的151个建议 建议148:增强类的可替换性
1700453581
1700453582
Java的三大特征:封装、继承、多态,这是每个初学者都会学习到的知识点,这里暂且不说封装和继承,单单说说多态。一个接口可以有多个实现方式,一个父类可以有多个子类,并且可以把不同的实现或子类赋给不同的接口或父类。多态的好处非常多,其中有一点就是增强了类的可替换性,但是单单一个多态特性,很难保证我们的类是完全可以替换的,幸好还有一个里氏替换原则来约束。
1700453583
1700453584
里氏替换原则是说“所有引用基类的地方必须能透明地使用其子类的对象”,通俗点讲,只要父类型能出现的地方子类型就可以出现,而且将父类型替换为子类型还不会产生任何错误或异常,使用者可能根本就不需要知道是父类型还是子类型。但是,反过来就不行了,有子类型出现的地方,父类型未必就能适应。
1700453585
1700453586
为了增强类的可替换性,就要求我们在设计类的时候考虑以下三点:
1700453587
1700453588
(1)子类型必须完全实现父类型的方法
1700453589
1700453590
子类型必须完全实现父类型的方法,难道还有能不实现父类型的方法?当然有,方法只是对象的行为,子类完全可以覆写,正常情况下覆写只会增强行为的能力,并不会“曲解”父类型的行为,一旦子类型的目的不是为了增强父类型行为,那替换的可能性就非常低了,比如这样的代码:
1700453591
1700453592
//枪
1700453593
1700453594
interface Gun{
1700453595
1700453596
//枪用来干什么的?射击杀戮!
1700453597
1700453598
public void shoot();
1700453599
[
上一页 ]
[ :1.70045355e+09 ]
[
下一页 ]