继承用的好,代码可扩展性好,用不好,就会出现类爆炸,继承破坏了开闭原则,父类发生变化,子类也要改变。一般优先使用组合或者聚合原则
组合是整体与部分的关系, 并且部分不可以离开整体而单独存在。组合一般是类的组合,是类的复用方式之一,优先于继承。
不破坏封装,整体类与局部类之间松耦合,彼此相对独立且有更好的可扩展性。
场景介绍:将地区区域分级表示,使用其他的方式很难将层次结构表达清楚,使用组合设计模式就非常方便。
public abstract class Node {
private String name;
public Node(String name){
this.name = name;
}
/**
* 获取子节点
* @return
*/
public abstract List<Node> getChildren();
public String getName() {
return name;
}
}
/**
- 叶子节点
*/
public class LeafNode extends Node{
public LeafNode(String name) {
super(name);
}
@Override
public List<Node> getChildren() {
return null;
}
}
/**
- 区节点
*/
public class DistrictNode extends Node{
private List<Node> children = new ArrayList<>();
public DistrictNode(String name) {
super(name);
}
@Override
public List<Node> getChildren() {
return children;
}
public void addChild(Node node){
children.add(node);
}
public void delChild(int i){
children.remove(i);
}
}
public static void main(String[] args) {
//根目录
DistrictNode root = new DistrictNode("root");
//一线目录
root.addChild(new DistrictNode("shang hai"));
root.addChild(new DistrictNode("tian jin"));
DistrictNode districtNode = new DistrictNode("bei jing");
root.addChild(districtNode);
//二级目录
districtNode.addChild(new DistrictNode("hai dian qu"));
districtNode.addChild(new DistrictNode("xi cheng qu"));
DistrictNode districtNode2 = new DistrictNode("chao yang qu");
districtNode.addChild(districtNode2);
//三级目录
districtNode2.addChild(new LeafNode("san li tun "));
districtNode2.addChild(new LeafNode("guo mao"));
System.out.println(JsonOutput.toJson(root));
}
使用组合模式,很清晰的将分层的数据进行组织,以后遇到类似这样的数据,可以采用这个方式处理。
聚合:
java// 首先定义一个飞行器接口
public interface Flyable {
void fly();
}
// 实现飞行器接口的飞机类
public class Airplane implements Flyable {
@Override public void fly() {
System.out.println(“Airplane is flying”);
}
}
// 实现飞行器接口的直升机类
public class Helicopter implements Flyable {
@Override public void fly() {
System.out.println(“Helicopter is flying”);
}
}
// 定义一个飞行器组合类,通过组合的方式实现复用
public class FlyingMachine {
private Flyable flyable;
public FlyingMachine(Flyable flyable) {
this.flyable = flyable;
}
public void performFly() {
flyable.fly();
}
}
// 测试类
public class Test {
public static void main(String[] args) {
//通过组合的方式创建一个飞行器 FlyingMachine airplane = new FlyingMachine(new Airplane());
airplane.performFly();
FlyingMachine helicopter = new FlyingMachine(new Helicopter());
helicopter.performFly();
}
}
在上面的示例中,我们定义了一个飞行器接口Flyable,然后分别实现了飞机类Airplane和直升机类Helicopter。接着我们定义了一个飞行器组合类FlyingMachine,通过组合的方式将飞行器接口作为成员变量,实现了复用的目的。
通过合成聚合复用原则,我们可以更灵活地组合已有的对象,而不是通过继承的方式来实现复用,从而降低类与类之间的耦合度,提高系统的灵活性。