20

From the standpoint of pure computer science (or perhaps computational linguisticis), I would like to know the difference between the words:

  • Decorator
  • Attribute
  • Aspect
  • Trait

Various Languages utilize these words and functionality in difference ways. In Python, for example, Decorators [according to the Python Wiki] (emphasis mine):

Decorators dynamically alter the functionality of a function, method, or class without having to directly use subclasses or change the source code of the function being decorated.

This strikes me as being remarkably similar to an Aspect Oriented Programming Tool like PostSharp or DynamicProxy. i.e.:

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

Source: PostSharp Examples

In C# and Java (as well as a myriad of other languages), attributes can either mean a Decorator-ish pattern (C#) or a field (Java).

And in C++ via boost or PhP via the builtin trait word, we can use traits to extend classes as shown here: https://en.wikipedia.org/wiki/Trait_(computer_programming)

So, from a "pure" standpoint, what is the canonical definitions of what all these actually are? Is there a better way to define them?

Darkenor
  • 4,349
  • 8
  • 40
  • 67
  • There is no standard between languages. Plus, I don't think all languages support the strict definition of each one. Take Java. Decorator = Annotation, Attribute = Field, Trait = Default method (maybe interface)... An Aspect, on the other hand is more a software architecture concept than a feature of any one language. – OneCricketeer Oct 27 '16 at 13:55
  • 1
    It stands to reason then that there be a paradigm-level "term" for each of these associated "things." I would have a difficult time believing from a theoretical perspective you couldn't quantify them mroe accurately. – Darkenor Oct 27 '16 at 13:59
  • How often do you really need to switch between programming languages to need to discuss the concepts rather than the actual terminology of the languages? The Wikipedia page of Trait and Aspect seem to be adequate in my understanding from high level. (Reference: https://en.m.wikipedia.org/wiki/Aspect_(computer_programming) ) But, if you're talking about Python and I'm talking about C#, and we both say decorators, then our understanding is probably different. – OneCricketeer Oct 27 '16 at 14:08
  • 2
    I'm not sure how that's relevant. The question is on theory and computer science. But the answer is frequently. I deal with a lot of different on different techs. – Darkenor Oct 27 '16 at 14:15
  • I see a lot of value in this question. For both computer languages or natural languages, semantic misunderstandings can be overcome more easily if people are aware how the languages evolved. It makes it easier to find the concepts in common, and identify differences in thinking. – Michael Scheper Apr 27 '17 at 17:40
  • I was also hoping somebody could clear up the difference between a _decorator_ and an _annotation_. My background is in both Java and Python, and as strong as some developers' assertions are about the correct term, I haven't heard any real reasoning, nor any correlation with either language. – Michael Scheper Apr 27 '17 at 17:44
  • 1
    @MichaelScheper An annotation does not directly modify behavior or add new behavior, while a decorator does. Annotations might indirectly change behavior, but an annotation is basically just metadata, extra info about a class. – Tim Jul 25 '17 at 18:57

1 Answers1

19

Decorator

I think of Decorator in terms of the design pattern. Design patterns are recognized in many languages, particularly object oriented ones. The decorator as a pattern, then, is a wrapper that adds functionality not present in the function or class being decorated.

The simplest example I can think of is a decorator function. The function

int foo(int x)

could be decorated by another function that accepts a second parameter, does something else with it, and then in turn calls foo(), passing the original parameter x.

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

While design patterns are typically applied at the class level, the principle here is the same, and I think it illustrates well what is meant by a decorator. Whether each particular language adheres to this is a different matter. One language might have something else that it calls a 'decorator' - but to me this concept best matches the idea of decorating something plain with additional functionality, without altering the original code or even using inheritance.

Another common example are the I/O classes in Java. There is the basic

OutputStream s

and then you can decorate this by using the more specialized classes depending on the type of data being dealt with, or the format you wish to read the data in:

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

or

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

Attribute

I would lean towards the C# idea of attribute being the correct understanding, because it is different from a decorator. An attribute assigns a semantic value which can vary from one use to another, and even between API's which use the same attribute. For example, I might have two functions:

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

I can assign one a logging attribute and one a security attribute, and what those attributes mean might be different to client API's that examine those attributes. One might use log4j to implement the logging and one might use another API. The definition here is much more fluid and open to interpretation by different parties or users of my code. One could certainly use an attribute to act as a decorator, but attributes can be used for much more than that.

Just for disambiguation, the word attribute is also used to denote member variables of a class. Here we are talking about the larger, more abstract concept of assigning a predefined semantic value to an existing object or class. Java calls these annotations.

One qualifier in my mind for it being an Attribute, in the sense we are talking about, is that it doesn't directly modify behavior, only indirectly. For example, assigning the [Logging] attribute to something doesn't change its code in any way. It's like attaching a name tag which others are looking for. When another program or application sees the name tag, it infers certain things and may change its behavior accordingly. But (at least in Java) annotations or attributes do not directly modify anything - again, just a name tag. This may be slightly different in C# or other languages that support attributes, in which case I would consider them to be a more advanced attribute or something else entirely.

Aspect

An aspect in the sense of aspect-oriented programming (AOP) is a sort of self-modifying or self-updating code construct. It defines a section of code as more malleable (a point cut) and allows that particular section to be swapped in and out between one or more possible updates, patches, or different versions of the same section of code.

Could you do some of the same things as decorators and attributes using aspects? Sure. But why would you give yourself that headache? AOP is like the next step up from OOP, only it should be used when necessary. When is it necessary? When a particular application has a lot of "cross-cutting concerns" like security or logging - for example, a banking application. These concerns cross-cut; they cross beyond the traditional boundaries which make nice defined classes and packages. When you are logging, it doesn't do a lot of good unless you log everything; hence, this concern is cross-cutting. So when you go to update one class's logging mechanism, it would be difficult to simultaneously modify all other classes and API's, but it would also be necessary. Otherwise your logging is now inconsistent and confusing, and more difficult to use for troubleshooting or monitoring.

To make these kinds of updates less of a headache, aspect oriented languages like AspectJ were introduced. I haven't run across an "aspect" that meant anything other than this, but there may be some as stated earlier about decorators. A particular language might call something an aspect, but it might look more like one of the other things we have already discussed.

Trait

Trait is synonymous with interface, or at least that's how it appears to be in the languages I've studied.

An interface is an OOP concept which declares behaviors without implementing them. Creating these expected behaviors allow those behaviors to become generic, and to be invoked generically without caring about specifics. It's left to the subclasses to implement them.

The classic OOP example is Animal, with two subclasses, Cat and 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!");
    }
}

This is also a great example of polymorphism - one of those words that tend to make non-computer folks cringe. It just means that cat and dog have individual behaviors, and if I declare an Animal object, I don't care what kind you give me. You can give me a cat or a dog. Because both are animals, in either case, all I have to do is call the speak() function of my Animal object, and I can rest assured that the correct result will occur in either case. Each individual subclass knows what it needs to do. In C++ the waters are a little more muddy here, but the general concept is the same (read into the keyword 'virtual' if you want to start down that rabbit hole).

Wrap-Up

I hope that clears up some of the confusion. It seems that, as you said, many different languages have many different meanings for each of these, no doubt contributing to the confusion. I believe that if you look into it further, you will find that by and large, these are the standard meanings. I have been programming in many languages (VB, C++, C#, Java, Paschal, PHP, Perl) for 18+ years and these are the definitions I am most comfortable with believing as a kind of standard.

I certainly welcome further discussion on what I have said.

Tim
  • 628
  • 5
  • 17
  • 4
    IMHO a trait goes far beyond an interface. An interface only declares, which methods can be found but don't provide an implementation. Traits also include the definition. So I see a trait more as some kind of *partial class* that can be *partial to multiple classes* – derM - not here for BOT dreams Jun 22 '17 at 09:06
  • 1
    @derM As stated in my answer, different languages have different meanings. I agree that traits CAN go far beyond being just an interface. I never stated they can't be anything more than that. When you distill down to what traits always mean versus what they can sometimes mean, you wind up with interface being the common denominator. I agree there's ambiguity there, but that's the nature of the discussion. Feel free to post your own answer that explains traits better. – Tim Jun 22 '17 at 14:57
  • Note that .NET attributes do not associate with _objects_ (instances), but with type-system entities (e.g. types, fields, properties, methods and parameters). I tend to see attributes as impotent tags or labels, which can provide great power to the compiler, runtime or custom code using reflection. – Robert Schmidt Sep 20 '18 at 06:59
  • @RobertSchmidt Thanks for the clarification. I'll edit to more precisely indicate this. – Tim Sep 21 '18 at 14:41