装饰
我觉得装饰的设计模式中的条款。设计模式在许多语言中都得到认可,尤其是面向对象的。然后,作为模式的装饰器是一个包装器,它添加了正在装饰的函数或类中不存在的功能。
我能想到的最简单的例子是装饰器功能。功能
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] Object a;
[Security] Object b;
我可以指定一个记录属性和一个安全属性,以及这些属性的意思可能是客户端API,可检查这些属性不同。可以使用log4j来实现日志记录,并且可以使用另一个API。这里的定义更加流畅,并且可供我的代码的不同方或用户解释。当然,我们可以使用一个属性来充当装饰器,但是属性可以被使用的远不止这些。
仅用于消歧,单词属性也用于表示类的成员变量。在这里我们正在讨论将更大,更抽象的概念分配给一个已经存在的对象或类的预定义语义值。 Java调用这些注释。
从我们所说的意义上来说,我认为它是一个属性的一个限定词就是它不直接修改行为,只是间接修改行为。例如,将[Logging]属性分配给某些内容不会以任何方式更改其代码。这就像附加其他人正在寻找的名称标签。当另一个程序或应用程序看到名称标签时,它会推断某些事情并可能相应地改变其行为。但是(至少在Java中)注释或属性不会直接修改任何东西 - 再次,只是一个名称标签。在C#或支持属性的其他语言中,这可能会略有不同,在这种情况下,我会认为它们是更高级的属性或其他完全不同的属性。
看点
在面向方面的编程(AOP)的意义上的一个方面是一种自修改或自更新代码构造的。它将一段代码定义为更具延展性(减少点数),并允许特定部分在一个或多个可能的更新,补丁或代码的相同部分的不同版本之间交换。
你可以使用方面做一些与装饰器和属性相同的东西吗?当然。但为什么你会让自己头痛? AOP就像OOP的下一步,只有在必要时才能使用它。何时需要?当一个特定的应用程序出现诸如安全性或日志记录等许多“交叉问题”时 - 例如,银行应用程序。这些关切是交叉的;它们超越了传统界限,它们可以定义好类和包。当你登录时,除非你记录所有的东西,否则它不会有很好的表现。因此,这种关切是交叉的。所以当你去更新一个类的日志记录机制时,很难同时修改所有其他的类和API,但也是必要的。否则,您的日志记录现在不一致且令人困惑,并且更难以用于故障排除或监视。
为了使这些更新不那么令人头疼,引入了AspectJ等面向方面的语言。我没有碰到除此之外任何其他意思的“方面”,但可能有一些如前所述关于装饰者。一种特定的语言可能称为某个方面,但它可能更像是我们已经讨论过的其他事情之一。
特质
性状与接口的代名词,或者至少这是它似乎是在我研究的语言。
接口是一种OOP概念,它在不实现它们的情况下声明行为。创建这些预期的行为允许这些行为变得通用,并且一般不需要关注具体细节就可以调用。它由子类来实现它们。
经典的面向对象的例子是动物,有两个子类,猫和狗。
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对象的speak()函数,我可以放心,无论哪种情况都会发生正确的结果。每个单独的子类都知道它需要做什么。在C++中,这里的水域更加泥泞,但是一般概念是相同的(如果你想开始这个兔子洞,可以读入关键字'虚拟')。
层的总结
我希望澄清了一些混乱。看起来,正如你所说,许多不同的语言对每一种语言都有不同的含义,毫无疑问是造成了混乱。我相信如果你进一步研究它,你会发现大体上这些都是标准的含义。我已经使用多种语言(VB,C++,C#,Java,Paschal,PHP,Perl)进行了18年以上的编程,这些是我最相信作为一种标准的定义。
我当然欢迎进一步讨论我所说的话。
语言之间没有标准。另外,我不认为所有的语言都支持每个语言的严格定义。以Java。 Decorator = Annotation,Attribute = Field,Trait =默认方法(可能是接口)...另一方面,Aspect更像是一种软件架构概念,而不是任何一种语言的特性。 –
对于这些相关的“事物”中的每一个,都有一个范式级别的术语。如果从理论的角度来看,我很难相信你无法准确地量化它们。 – Darkenor
您是否真的需要在编程语言之间切换,以便讨论概念而不是语言的实际术语? Trait和Aspect的维基百科页面似乎足以让我从高层理解。 (参考:https://en.m.wikipedia.org/wiki/Aspect_(computer_programming))但是,如果你在谈论Python并且我在谈论C#,并且我们都说装饰器,那么我们的理解可能就是不同。 –