组合/聚合复用原则
组合/聚合复用原则表示在一个新的对象里通过关联关系(组合关系或者聚合关系)来使用一些已有的对象,使之成为新对象的一部分;新对象通过委派调用已有对象的方法达到复用其已有功能的目的。也就是说,要尽量使用组合或者聚合,而不是使用继承来达到复用的目的。
组合/聚合复用原则是面向对象设计的重要原则之一,它体现了类之间的关联和组合。如果一个软件能够遵循组合/聚合复用原则,那么它就具有以下两个优点:
- 降低了类之间的耦合性,提高了系统的灵活性。
- 提高了代码的可重用性,避免了继承带来的缺点。
举个例子,假设我们有一个动物类 Animal,它有一个方法 eat(),表示动物可以吃东西。然后我们定义了一个狗类 Dog 和一个鸟类 Bird 来继承 Animal 类,并实现 eat() 方法。但是,我们发现狗类和鸟类还有一些其他的行为,比如狗可以叫,鸟可以飞。这些行为和 eat() 方法没有什么关系,但是却被放在了同一个类中。代码如下:
代码语言:javascript复制class Animal {
public void eat() {
System.out.println("动物可以吃东西");
}
}
class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃骨头");
}
public void bark() {
System.out.println("狗会叫");
}
}
class Bird extends Animal {
@Override
public void eat() {
System.out.println("鸟吃虫子");
}
public void fly() {
System.out.println("鸟会飞");
}
}
这个类违反了组合/聚合复用原则,因为它使用了继承来达到复用的目的。这样的设计有以下几个缺点:
- 类之间的耦合度高,如果 Animal 类发生变化,就会影响到所有继承它的类。
- 代码的可重用性差,因为 Animal 类包含了一些不必要的方法。
- 代码的灵活性差,如果我们想要增加新的动物类型或者新的行为,就需要修改 Animal 类或者继承它的类。
为了遵循组合/聚合复用原则,我们应该将 Animal 类设计成一个接口,并定义一个抽象方法 eat()。然后,针对不同的动物类型和行为,定义不同的类来实现 Animal 接口或者组合其他类。这样,在程序中可以根据需要选择实现哪些接口或者组合哪些类,而不强制继承不必要的接口或者类。代码如下:
代码语言:javascript复制interface Animal {
public void eat();
}
class Dog implements Animal {
private Barkable barkable;
public Dog(Barkable barkable) {
this.barkable = barkable;
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
public void bark() {
barkable.bark();
}
}
class Bird implements Animal {
private Flyable flyable;
public Bird(Flyable flyable) {
this.flyable = flyable;
}
@Override
public void eat() {
System.out.println("鸟吃虫子");
}
public void fly() {
flyable.fly();
}
}
interface Barkable {
public void bark();
}
interface Flyable {
public void fly();
}
class BigDog implements Barkable {
@Override
public void bark() {
System.out.println("大狗汪汪叫");
}
}
class SmallDog implements Barkable {
@Override
public void bark() {
System.out.println("小狗呜呜叫");
}
}
class Eagle implements Flyable {
@Override
public void fly() {
System.out.println("老鹰在天空飞");
}
}
class Sparrow implements Flyable {
@Override
public void fly() {
System.out.println("麻雀在树上飞");
}
}
// 其他动物类型和行为的实现类省略