当前位置: 首页 > 知识库问答 >
问题:

Kotlin 扩展类如何取代装饰器设计模式?

公良鸿禧
2023-03-14

静态编程语言的留档声明如下:

Kotlin 提供了一种使用新功能扩展类的能力,而不必从类继承或使用设计模式(如装饰器)。

Kotlin 扩展

我很难理解扩展函数如何完全取代装饰器设计模式。

借用TutorialPoint的一个例子,你如何把下面的例子变成只使用扩展函数的代码?您能在不牺牲对具体形状对象和修饰形状对象调用< code>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();
}

Java 中的教程点示例

共有1个答案

逑景铄
2023-03-14

这似乎是一个设计推理或哲学的问题。第一个装饰器模式被称为包装器类。包装器/装饰器这样做是为了向feature(正在包装的)/wrappee的用户隐藏细节,添加或更改wrappee中的某个特性。然后它添加了一层抽象。通过这种抽象,如果需要的话,它可以在将来轻松地更改wrappee类。在你的例子中,我看不到ShapeDecorator/ShapeWrapper的用途-它真正的包装是什么,用于什么目的?-接口本身就是一个合同。

在 Kotlin 中,默认情况下所有类

现在来看看Extension和Wrapper之间的区别。如果您只需要扩展以添加基类的原始创建者遗漏的一些功能,并且您不能在基类中进行更改,或者觉得这不是进行更改的正确位置,那么您将选择扩展功能。它没有隐藏任何内容,也没有添加任何抽象层(一个或多个)。但如果它是为了抽象、装饰的目的,那么你就选择装饰家。扩展函数不替换装饰器模式。如果不需要,可以避免。

扩展也是由静态调度提供资金——用非常非常简单的话来说,它们在java反编译中变成了静态方法(因此你再次看到了抽象的缺失)。

这是一个快速写好的答案。

 类似资料:
  • 扩展 扩展是一种十分强大的机制,可以让你在不用继承的情况下,给已存在的类、结构体或者枚举类添加一些新的功能。最重要的一点是,你可以在你没有访问权限的情况下扩展已有类。这意味着你甚至可以扩展 Cocoa 的类,比如 UIView 或者 UIImage 。 举个例子,在编译时新加的方法可以像扩展类的正常方法一样执行。这和装饰器模式有点不同,因为扩展不会持有扩展类的对象。

  • 如何使用扩展 想象一下这个场景,我们需要在下面这个列表里展示数据: 专辑标题从哪里来? Album 本身是个 Model 对象,所以它不应该负责如何展示数据。你需要一些额外的代码添加展示数据的逻辑,但是为了保持 Model 的干净,我们不应该直接修改代码,因为这样不符合单一职责原则。 Model 层最好就是负责纯粹的数据结构,如果有数据的操作可以放到扩展中完成。 接下来我们会创建一个扩展,扩展现有

  • 装饰(Decorator) Intent 为对象动态添加功能。 Class Diagram 装饰者(Decorator)和具体组件(ConcreteComponent)都继承自组件(Component),具体组件的方法实现不需要依赖于其它对象,而装饰者组合了一个组件,这样它可以装饰其它装饰者或者具体组件。所谓装饰,就是把这个装饰者套在被装饰者之上,从而动态扩展被装饰者的功能。装饰者的方法有一部分是

  • 当我回顾了“decorator”设计模式的大量示例时,我刚刚想到了一些示例,这些示例主要是关于更改总是返回字符串的方法,或者像cost()这样聚合数字的方法。 这真的是装饰器设计模式的唯一用法吗? 我只知道它用于Java IO API。 但我想有其他的东西,打印一个文本。一些真实的东西。我找了那么多,却找不到合适的样品。

  • 问题内容: 假设我有一个名为的类,并且我想使用装饰器设计模式。如果我错了,请纠正我,但是要使其正常工作,我们需要创建一个装饰器类,例如,该类将保留对实例的引用,所有其他装饰器将对其进行扩展以添加功能。 我不明白为什么我们必须创建装饰器类而不是使用实例? 问题答案: 装饰器模式用于动态地(即在运行时)向对象添加功能。通常,在编写类时,对象将具有固定的功能。但是重要的一点是,对象的功能以对对象的客户端

  • 12.4 透明装饰模式与半透明装饰模式 装饰模式虽好,但存在一个问题。如果客户端希望单独调用具体装饰类新增的方法,而不想通过抽象构件中声明的方法来调用新增方法时将遇到一些麻烦,我们通过一个实例来对这种情况加以说明: 在Sunny软件公司开发的Sunny OA系统中,采购单(PurchaseRequest)和请假条(LeaveRequest)等文件(Document)对象都具有显示功能,现在要为其增