gpt4 book ai didi

computer-science - 装饰器,属性,方面和特质有什么区别?

转载 作者:行者123 更新时间:2023-12-03 14:58:57 25 4
gpt4 key购买 nike

从纯计算机科学(或也许是计算语言学)的角度,我想知道以下单词之间的区别:


装饰器
属性
方面
特征



各种语言以不同的方式利用这些单词和功能。例如,在Python中,Decorators [根据Python Wiki](重点是我的):


装饰器可以动态更改功能,方法或类的功能,而不必直接使用子类或更改要修饰的功能的源代码。


这让我感到惊讶,因为它与面向方面的编程工具(如PostSharp或DynamicProxy)非常相似。即:

   [Profile]
private static void SleepSync()
{
Thread.Sleep(200);
}


资料来源: PostSharp Examples

在C#和Java(以及多种其他语言)中,属性可以表示Decorator-ish模式(C#)或字段(Java)。

在C ++中通过boost或通过内置的trait词的PhP,我们可以使用traits扩展类,如下所示: https://en.wikipedia.org/wiki/Trait_(computer_programming)

那么,从“纯粹”的角度来看,所有这些实际上是什么的规范定义是什么?有没有更好的方法来定义它们?

最佳答案

装饰器

我认为Decorator在设计模式方面。设计模式在许多语言中都得到认可,尤其是面向对象的语言。装饰器作为一种模式,然后是一个包装器,用于添加要装饰的函数或类中不存在的功能。

我能想到的最简单的示例是装饰器函数。功能

int foo(int x)


可以由接受第二个参数,用第二个参数做其他事情的另一个函数修饰,然后依次调用foo()并传递原始参数x。

int bar(int x, int y) {
return y*y + foo(x);
}


虽然设计模式通常应用于类级别,但是这里的原理是相同的,我认为它很好地说明了装饰器的含义。是否每种特定的语言都遵守这一点是不同的问题。一种语言可能还有其他被称为“装饰器”的东西-但对我来说,这个概念最适合用简单的东西用附加功能装饰东西,而无需更改原始代码甚至不使用继承。

另一个常见的示例是Java中的I / O类。有基本的

OutputStream s


然后您可以根据所处理的数据类型或希望以以下方式读取数据的格式,使用更专门的类来修饰它:

OutputStream s1 = new FileOutputStream("somefile.txt");


要么

OutputStream s2 = new ByteOutputStream("rawdata.hex");


属性

我倾向于属性的C#概念是正确的理解,因为它与装饰器不同。属性分配的语义值可能因一种用途而异,甚至在使用相同属性的API之间也会有所不同。例如,我可能有两个功能:

[Logging] private void a() { ... }
[Security] private void b() { ... }


我可以分配一个日志记录属性,一个安全性属性,这些属性的含义可能与检查这些属性的客户端API不同。一个人可能使用log4j来实现日志记录,一个人可能使用另一种API。这里的定义更加流畅,可以让各方或我的代码用户进行解释。当然可以使用属性来充当装饰器,但是使用属性的作用远不止于此。

只是为了消除歧义,单词属性还用于表示类的成员变量。在这里,我们讨论的是为现有对象或类分配预定义语义值的更大,更抽象的概念。 Java调用这些注释。

在我看来,将其定义为属性的一种限定词是它不会直接修改行为,而只会间接地修改行为。例如,将[Logging]属性分配给某物不会以任何方式更改其代码。这就像附加其他人正在寻找的名称标签一样。当另一个程序或应用程序看到名称标签时,它将推断某些事情,并可能相应地更改其行为。但是(至少在Java中)注释或属性不会直接修改任何内容-再次只是名称标签。在C#或其他支持属性的语言中,这可能会稍有不同,在这种情况下,我会认为它们是更高级的属性或完全其他的属性。

方面

面向方面编程(AOP)方面的一个方面是一种自我修改或自我更新的代码构造。它将一段代码定义为更具延展性(切入点),并允许在同一代码部分的一个或多个可能的更新,补丁或不同版本之间交换该特定部分。

您可以使用方面做一些与装饰器和属性相同的事情吗?当然。但是,为什么要让自己头痛呢? AOP就像是OOP的下一步,只有在必要时才应使用。什么时候有必要?当特定的应用程序有很多“跨领域问题”,例如安全性或日志记录时,例如银行应用程序。这些问题相互交叉;它们跨越了传统的界限,这些界限构成了很好的定义的类和包。当您记录日志时,除非您记录所有内容,否则它并不会带来很多好处。因此,这种关注是跨领域的。因此,当您更新一个类的日志记录机制时,很难同时修改所有其他类和API的日志记录,但这也是必要的。否则,您的日志记录现在变得不一致且令人困惑,并且更难以用于故障排除或监视。

为了使这些更新不再令人头疼,引入了诸如AspectJ之类的面向方面的语言。除此以外,我还没有遇到过“方面”,但是可能有一些前面提到的关于装饰器的问题。一种特定的语言可能将某事物称为一个方面,但它看起来更像是我们已经讨论过的其他事物之一。

特征

特性是接口的代名词,或者至少这就是我所研究的语言中的接口。

接口是一个OOP概念,它声明行为而不执行它们。创建这些预期的行为可使这些行为成为通用行为,并且无需关心具体细节即可被通用调用。留给子类来实现它们。

经典的OOP示例是Animal,具有两个子类Cat和Dog。

public interface/trait Animal {
public void speak();
}
public class Cat implements Animal {
public void speak() {
output("Meow.");
}
}
public class Dog implements Animal {
public void speak() {
output("Bark!");
}
}


这也是多态性的一个很好的例子-那些容易使非计算机人士畏缩的词语之一。这只是意味着猫和狗有各自的行为,如果我声明了Animal对象,则不管您给我什么样的东西。你可以给我猫或狗。因为两者都是动物,所以在任何一种情况下,我要做的就是调用我的Animal对象的talk()函数,并且我可以放心,无论哪种情况都会出现正确的结果。每个子类都知道它需要做什么。在C ++中,这里的水有些混浊,但是一般概念是相同的(如果您想从那个兔子洞开始读入关键字“虚拟”)。

包起来

我希望这可以消除一些困惑。正如您所说,似乎许多不同的语言对每种语言都有许多不同的含义,这无疑会造成混乱。我相信,如果您进一步研究它,您会发现它们基本上是标准含义。我已经用多种语言(VB,C ++,C#,Java,Paschal,PHP,Perl)编程了18年以上,这些都是我最相信的一种定义。

我当然欢迎就我所说的进一步讨论。

关于computer-science - 装饰器,属性,方面和特质有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40164727/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com