设计模式(java语言)

设计模式


前言

提示:我是彩笔,所以能理解菜的人的感受。这些都在心路历程中,不想看的可跳过。

结构型模式

一、装饰器模式(2023/12/27)

1. 解决的需求

在不改变对象结构的情况下动态的添加功能或责任

2. 心路历程

假定我们现在要实现四个类,普通咖啡(5元),加了糖(2元)的普通咖啡,加了奶(3元)的普通咖啡,既加糖又加奶的普通咖啡。我们应该怎么做才能更好地复用呢?

class SimpleCoffee{
	public int cost(){
		return 5;
	}
}

class SugerCoffee{
	public int cost(){
		return 5+2;
	}
}

class MilkCoffee{
	public int cost(){
		return 5+3;
	}
}

class SugerAndMilkCoffee{
	public int cost(){
		return 5+3+2;
	}
}

但凡在多加一个种类,比如椰果,会发现类的数量呈指数增长。所以要优化

步骤一: 消除重复代码


class SimpleCoffee {
	public int cost(){
		return 5;
	}
}

class sugerCoffee extends SimpleCoffee{
	@Override
	public int cost(){
		return super.cost() + 2;
	}
}

class MilkCoffee extends SimpleCoffee {
    @Override
    public int cost() {
        return super.cost() + 3;
    }
}

class SugarAndMilkCoffee extends SimpleCoffee {
    @Override
    public int cost() {
        return super.cost() + 3 + 2;
    }
}

在这一步中,我们通过让SugarCoffee、MilkCoffee和SugarAndMilkCoffee扩展SimpleCoffee,消除了一些重复代码。现在,它们继承了SimpleCoffee的基本成本,并添加了各自的特定成本。

步骤2:引入接口

interface Coffee{
	int cost();
}
class SimpleCoffee implements Coffee{
	@Override
	public int cost(){
		return 5;
	}
}

class SugerCoffee implements Coffee{
	
	private final Coffee coffee;
	
	public SugerCoffee(Coffee coffee){
		this.coffee =  coffee;
	}

	@Override
	public int cost(){
		return coffee.cost() + 2;
	}
}

class MilkCoffee extends SimpleCoffee {

	private final Coffee coffee;
	
	public MilkCoffee(Coffee coffee) {
        this.coffee = coffee;
    }
	
    @Override
    public int cost() {
        return coffee.cost() + 3;
    }
}

class SugarAndMilkCoffee extends SimpleCoffee {

	private final Coffee coffee;

    public SugarAndMilkCoffee(Coffee coffee) {
        this.coffee = coffee;
    }
    
    @Override
    public int cost() {
        return coffee.cost() + 3 + 2;
    }
}

现在,我们引入了Coffee接口,每种咖啡类型都实现了该接口。我们还为每个类添加了构造函数,以组合基本咖啡的成本。
将private final Coffee coffee; 添加到MilkCoffee 类中是为了引入一种称为组合的设计模式。这是为了使MilkCoffee 可以包含另一种 Coffee 对象,并在其基础上添加额外的功能(在这个例子中是添加牛奶的成本)。

步骤3:分离关注点

3. 最终示例代码

interface Coffee {
    int cost();
}

class SimpleCoffee implements Coffee {
    @Override
    public int cost() {
        return 5;
    }
}

abstract class CoffeeDecorator implements Coffee {
    private final Coffee coffee;

    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    @Override
    public int cost() {
        return coffee.cost();
    }
}

class SugarCoffee extends CoffeeDecorator {
    public SugarCoffee(Coffee coffee) {
        super(coffee);
    }

    @Override
    public int cost() {
        return super.cost() + 2;
    }
}

class MilkCoffee extends CoffeeDecorator {
    public MilkCoffee(Coffee coffee) {
        super(coffee);
    }

    @Override
    public int cost() {
        return super.cost() + 3;
    }
}

在这一步中,我们引入了CoffeeDecorator抽象类,它实现了Coffee接口,并包含了一个Coffee实例。这样,我们可以在具体的装饰器类中扩展咖啡的成本,而不影响基本咖啡类。

让我们解释一下这个设计:

  1. 接口 Coffee: 定义了 cost() 方法,表示咖啡的成本。

  2. 基本咖啡类 SimpleCoffee: 实现了 Coffee 接口,表示没有额外成本的基本咖啡。

  3. 装饰器抽象类 CoffeeDecorator: 实现了 Coffee 接口,包含一个 Coffee 对象作为成员变量,通过组合来扩展基础咖啡的功能。

  4. 具体装饰器类 MilkCoffee: 继承了 CoffeeDecorator,并通过构造函数接收另一个 Coffee 对象(即被装饰的咖啡),然后在 cost() 方法中添加额外的成本(牛奶的成本)。

通过这样的设计,我们可以轻松地组合不同的装饰器,以获得不同组合的咖啡,而不需要修改基础咖啡类或其他装饰器类。这符合开放/封闭原则,即对修改关闭,对扩展开放。

总结

提示:距离总结还有一会

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值