【发布时间】:2021-07-01 00:22:36
【问题描述】:
Kotlin 的文档做出了这样的声明:
Kotlin 提供了使用新功能扩展类的能力 无需从类继承或使用设计模式,例如 作为装饰者。
我无法理解扩展函数如何完全替代装饰器设计模式。
借用 TutorialPoint 的一个例子,你如何把下面的例子变成只使用扩展函数的代码?您能否在不牺牲对具体形状对象和装饰形状对象调用 draw() 的能力的情况下做到这一点?
interface Shape {
fun draw();
}
class Rectangle: Shape {
override fun draw() {
println("Shape: Rectangle")
}
}
class Circle: Shape {
override fun draw() {
System.out.println("Shape: Circle");
}
}
abstract class ShapeDecorator(protected val decoratedShape: Shape): Shape {
override fun draw(){
decoratedShape.draw();
}
}
class RedShapeDecorator(decoratedShape:Shape): ShapeDecorator(decoratedShape) {
override fun draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
}
private fun setRedBorder(decoratedShape:Shape){
System.out.println("Border Color: Red");
}
}
fun main(){
val circle: Shape = Circle();
val redCircle: Shape = RedShapeDecorator(Circle());
val redRectangle: Shape = RedShapeDecorator(Rectangle());
System.out.println("Circle with normal border");
circle.draw();
System.out.println("\nCircle of red border");
redCircle.draw();
System.out.println("\nRectangle of red border");
redRectangle.draw();
}
【问题讨论】:
-
扩展并不能替代所有可能使用的装饰器模式。您引用的声明只是说它可以如果您仅使用该模式将函数添加到类而不对其进行子类化,则可以避免对装饰器模式的需要。
-
好的,如果具体装饰器向具体装饰类中的方法添加额外代码,那么扩展不能替换装饰器设计模式?在 RedShapeDecorator 中的示例 draw() 中打印“边框颜色:红色”以及形状名称。这不能用扩展重写吗?
-
这个例子与扩展函数的作用不同,因为它们不能影响继承或覆盖函数。
-
Kotlin 文档中的这个声明说扩展只是扩展现有类的另一种方式。扩展与装饰器模式或子类型有很大不同,因为用户需要有意使用它们,而子类型/装饰器对用户是透明的。这就是为什么扩展不能真正替代其他模式的原因。它们只是另一种方便的工具,比装饰器更轻巧,但功能有限。
标签: kotlin design-patterns decorator