这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
在上述场景中,当咖啡的内容不断丰富,咖啡价格也要做相应调整,装饰器的作用是让代码优雅的应对变化,对内代码整洁低耦合,对外保持统一接口getPrice
装饰器模式本身并不是本篇的重点,咱们还是聚焦quarkus下的装饰器功能:在咖啡价格的基础上,通过装饰器计算出拿铁的价格
接下来开始编码
package com.bolingcavalry.decorator;
public interface Coffee {
/**
* 咖啡名称
* @return
*/
String name();
/**
* 当前咖啡的价格
* @return
*/
int getPrice();
}
package com.bolingcavalry.decorator.impl;
import com.bolingcavalry.decorator.Coffee;
import javax.enterprise.context.ApplicationScoped;
/**
* 意式浓缩咖啡,价格3美元
*/
@ApplicationScoped
public class Espresso implements Coffee {
@Override
public String name() {
return "Espresso";
}
@Override
public int getPrice() {
return 3;
}
}
package com.bolingcavalry.decorator.impl;
import com.bolingcavalry.decorator.Coffee;
import io.quarkus.arc.Priority;
import io.quarkus.logging.Log;
import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.inject.Inject;
@Decorator
@Priority(11)
public class Latte implements Coffee {
/**
* 牛奶价格:2美元
*/
private static final int MILK_PRICE = 2;
@Delegate
@Inject
Coffee delegate;
@Override
public String name() {
return "Latte";
}
@Override
public int getPrice() {
// 将Latte的代理类打印出来,看quarkus注入的是否正确
Log.info("Latte's delegate type : " + this.delegate.name());
return delegate.getPrice() + MILK_PRICE;
}
}
package com.bolingcavalry.decorator.impl;
import com.bolingcavalry.decorator.Coffee;
import io.quarkus.arc.Priority;
import io.quarkus.logging.Log;
import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.inject.Inject;
/**
* 焦糖玛奇朵:拿铁+焦糖
*/
@Decorator
@Priority(10)
public class CaramelMacchiato implements Coffee {
/**
* 焦糖价格:1美元
*/
private static final int CARAMEL_PRICE = 1;
@Delegate
@Inject
Coffee delegate;
@Override
public String name() {
return "CaramelMacchiato";
}
@Override
public int getPrice() {
// 将CaramelMacchiato的代理类打印出来,看quarkus注入的是否正确
Log.infov("CaramelMacchiato's delegate type : " + this.delegate.name());
return delegate.getPrice() + CARAMEL_PRICE;
}
}
@Delegate
@Inject
Coffee delegate;
package com.bolingcavalry;
import com.bolingcavalry.decorator.Coffee;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import javax.inject.Inject;
@QuarkusTest
public class DecoratorTest {
@Inject
Coffee coffee;
@Test
public void testDecoratorPrice() {
Assertions.assertEquals(6, coffee.getPrice());
}
}
执行单元测试,如下图,单元测试通过表示coffee注入的是CaramelMacchiato类型的bean,再看右侧的日志,CaramelMacchiato的成员变量delegate是Latte类型,Latte的成员变量delegate是Espresso类型,都按照咱们的预期准确注入了
紧接着再做个尝试:将Latte的注解Priority的属性值改小,小于CaramelMacchiato的10,如下图红框,如此一来,CaramelMacchiato的优先级更大,因此更靠近Espresso,由它去装饰Espresso,Latte离Espresso更远,所以它装饰的是CaramelMacchiato