设计模式解析:组合模式与装饰模式

组合模式

动机

在软件开发中,处理整体与部分之间的关系时,组合模式是常用的设计选择。此模式将对象组织为树形结构,让客户端能统一对待单个对象和组合对象,简化操作。

结构

组合模式包含以下角色:

  • Component(抽象构件):定义叶子和容器对象的共同接口,提供一些默认行为。
  • Leaf(叶子):表示树的叶子节点,无法再分解。
  • Composite(容器):表示可以包含其他叶子或容器节点的容器对象。
  • Client(客户端):通过Component接口对组合对象进行操作。

示例代码

// 抽象构件
interface Component {
    void operation();
}

// 叶子节点
class Leaf implements Component {
    public void operation() {
        // 叶子节点的实现
    }
}

// 容器节点
class Composite implements Component {
    private List<Component> children = new ArrayList<>();

    public void add(Component component) {
        children.add(component);
    }

    public void remove(Component component) {
        children.remove(component);
    }

    public void operation() {
        for (Component component : children) {
            component.operation();
        }
    }
}

// 客户端代码
Component leaf1 = new Leaf();
Component leaf2 = new Leaf();
Composite composite = new Composite();
composite.add(leaf1);
composite.add(leaf2);
composite.operation();

优缺点

优点:

  • 统一处理单个对象与组合对象,简化客户端逻辑。
  • 易于扩展和修改整体结构,符合开闭原则。

缺点:

  • 增加系统复杂性,需理解组合模式的概念。

装饰模式

动机

在软件开发中,经常需要给对象添加额外功能而不修改其原始类。传统的继承方式容易导致类的增多,且静态继承关系无法在运行时动态改变。装饰模式通过组合和委托的方式灵活地为对象添加功能,同时保持原有接口及行为。

结构

装饰模式包含以下角色:

  • Component(抽象构件):定义原始类与装饰类的公共接口,可以是抽象类或接口。
  • ConcreteComponent(具体构件):实现Component接口的原始类,可以被装饰。
  • Decorator(抽象装饰类):实现Component接口,并持有一个Component引用,通过构造函数或setter方法注入。
  • ConcreteDecorator(具体装饰类):继承Decorator类,通过调用父类的方法扩展对象功能。

示例代码

// 抽象构件
interface Component {
    void operation();
}

// 具体构件
class ConcreteComponent implements Component {
    public void operation() {
        // 具体实现
    }
}

// 抽象装饰类
class Decorator implements Component {
    private Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    public void operation() {
        component.operation();
    }
}

// 具体装饰类
class ConcreteDecorator extends Decorator {
    public ConcreteDecorator(Component component) {
        super(component);
    }

    public void operation() {
        super.operation();
        // 扩展功能
    }
}

// 客户端代码
Component component = new ConcreteDecorator(new ConcreteComponent());
component.operation();

在示例中,通过装饰模式动态添加功能而不需修改原始类。结合组合和委托,可在运行时灵活添加、删除功能,并支持多层嵌套。

优缺点

优点:

  • 灵活地动态添加功能,比继承更优。
  • 支持嵌套装饰,实现更复杂功能扩展。
  • 遵循开闭原则,无需修改原始类即可扩展功能。

缺点:

  • 增加类数量,可能导致类膨胀。
  • 装饰链过长时,影响执行效率。

变形金刚实例中的装饰模式

动机

在变形金刚中,每个角色都有不同形态,比如机器人和车辆。我们希望在运行时动态切换这些形态,而不改变其原有行为。

结构

变形金刚实例包含以下角色:

  • Transformable(可变形接口):定义变形方法。
  • Transformer(变形金刚抽象类):实现可变形接口,提供默认行为。
  • CarTransformer(车辆变形金刚):实现车辆形态的变形方法。
  • RobotTransformer(机器人变形金刚):实现机器人形态的变形方法。

示例代码

// 可变形接口
interface Transformable {
    void transform();
}

// 变形金刚抽象类
abstract class Transformer implements Transformable {
    protected String name;

    public Transformer(String name) {
        this.name = name;
    }

    public void transform() {
        System.out.println(name + " 正在变形...");
    }
}

// 车辆变形金刚类
class CarTransformer extends Transformer {
    public CarTransformer(String name) {
        super(name);
    }

    public void transform() {
        super.transform();
        System.out.println(name + " 变身为车辆。");
    }
}

// 机器人变形金刚类
class RobotTransformer extends Transformer {
    public RobotTransformer(String name) {
        super(name);
    }

    public void transform() {
        super.transform();
        System.out.println(name + " 变身为机器人。");
    }
}

// 客户端代码
Transformable bumblebee = new CarTransformer("大黄蜂");
bumblebee.transform();

Transformable optimusPrime = new RobotTransformer("擎天柱");
optimusPrime.transform();

在示例中,使用装饰模式实现变形金刚实例。Transformer类是抽象类,实现可变形接口并提供默认变形方法,CarTransformer和RobotTransformer分别实现车辆和机器人形态的变形。这样可在运行时动态切换形态,而无需修改原有类结构,实现灵活及扩展性。

优缺点

优点:

  • 动态切换对象形态,提高灵活性。
  • 在运行时增减功能,无需修改原有结构。
  • 支持多层嵌套装饰,实现复杂功能。

缺点:

  • 增加类数量,可能导致类膨胀。
  • 装饰链过长时,可能影响执行效率。
  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值