2016-10-20 15 views
11

С точки зрения чистой вычислительной техники (или, возможно, вычислительной linguisticis), я хотел бы знать разницу между словами:В чем разница между Decorator, Attribute, Aspect и Trait?

  • декоратора
  • Атрибут
  • Аспект
  • Черта

Различные языки используют эти слова и функциональные возможности разным образом. В Python, например, Декораторы [в соответствии с Python вики] (курсив мой):

Декораторы динамически изменяют функциональные возможности функции, метода или класса без необходимости непосредственного использования подклассы или изменить источник код декодируемой функции.

Это поражает меня как удивительно похожего на инструмент ориентированного на перспективу программирования, такого как PostSharp или DynamicProxy. т.е .:

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

Источник: PostSharp Examples

В C# и Java (а также множество других языков), атрибуты могут означать либо декоратора-иш шаблон (C#) или поля (Java).

И в C++ с помощью усиления или PhP через встроено черты слова, мы можем использовать черты, чтобы расширить классы, как показано здесь: https://en.wikipedia.org/wiki/Trait_(computer_programming)

Таким образом, из «чистой» точки зрения, что канонические определения что все это на самом деле? Есть ли лучший способ определить их?

+0

Между языками нет стандарта. Кроме того, я не думаю, что все языки поддерживают строгое определение каждого из них. Возьмите Java. Decorator = Annotation, Attribute = Field, Trait = Метод по умолчанию (возможно, интерфейс) ... Аспект, с другой стороны, является скорее концепцией архитектуры программного обеспечения, чем функцией любого языка. –

+1

Понятно, что для каждого из этих связанных «вещей» существует «термин» уровня парадигмы. Мне было бы трудно полагаться на теоретическую перспективу, которую вы не могли бы точно оценить их mroe точно. – Darkenor

+0

Как часто вам нужно переключаться между языками программирования, чтобы обсуждать концепции, а не настоящую терминологию языков? Страница Википедии Trait and Aspect кажется адекватной в моем понимании с высокого уровня. (Ссылка: https://en.m.wikipedia.org/wiki/Aspect_(computer_programming)) Но, если вы говорите о Python, и я говорю о C#, и мы оба говорим о декораторах, то наше понимание, вероятно, другой. –

ответ

3

декоратор

Я думаю Decorator с точки зрения дизайна шаблона. Шаблоны проектирования распознаются на многих языках, особенно объектно-ориентированных. Таким образом, декоратор в качестве шаблона представляет собой оболочку, которая добавляет функциональность, не присутствующую в функции или классе, украшенном.

Простейший пример, который я могу придумать, - это функция декоратора. Функция

int foo(int x) 

может быть украшено другой функцией, которая принимает второй параметр, делает что-то еще с ним, а затем в свою очередь, вызывает Foo(), передавая исходный параметр х.

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

Хотя шаблоны проектирования, как правило, применяется на уровне класса, принцип здесь то же, и я думаю, что это хорошо иллюстрирует то, что подразумевается под декоратором. Соответствует ли каждый конкретный язык этому вопросу. На одном языке может быть что-то другое, что он называет «декоратором», - но для меня эта концепция лучше всего соответствует идее декорирования чего-то простого с дополнительной функциональностью, без изменения исходного кода или даже с использованием наследования.

Другим распространенным примером являются классы ввода-вывода в Java.Существует основная

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# или на других языках, поддерживающих атрибуты, и в этом случае я бы рассматривал их как более продвинутый атрибут или что-то еще.

Аспект

Один аспекта в смысле аспект-ориентированное программирование (АОП) является своим родом самомодифицирующегося или самостоятельного обновление конструкции коды. Он определяет секцию кода как более податливую (точечный снимок) и позволяет обменивать конкретный раздел между одним или несколькими возможными обновлениями, исправлениями или разными версиями одного и того же раздела кода.

Не могли бы вы сделать некоторые из тех же вещей, что и декораторы и атрибуты, используя аспекты? Конечно. Но почему бы вам дать эту головную боль? АОП походит на следующий шаг вверх от ООП, только он должен использоваться, когда это необходимо. Когда это необходимо? Когда конкретное приложение имеет множество «сквозных проблем», таких как безопасность или ведение журнала, например, банковское приложение. Это касается перекрестного разреза; они выходят за рамки традиционных границ, которые делают хорошие определенные классы и пакеты. Когда вы регистрируетесь, это не очень полезно, если вы не регистрируете все; следовательно, эта проблема является сквозной. Поэтому, когда вы переходите к обновлению механизма регистрации одного класса, было бы трудно одновременно модифицировать все другие классы и API, но это также было бы необходимо. В противном случае ваше ведение журнала теперь непоследовательно и запутанно, и более сложно использовать для устранения неполадок или мониторинга.

Чтобы сделать эти виды обновлений меньше головной боли, были представлены аспектно-ориентированные языки, такие как AspectJ. Я не сталкивался с «аспектом», который означал что-то другое, кроме этого, но могут быть некоторые, как было сказано ранее, о декораторах. Определенный язык может называть что-то одним аспектом, но он может походить на одну из других вещей, которые мы уже обсуждали.

Черта

Черта является синонимом интерфейса, или, по крайней мере, как представляется, в языках я изучал.

Интерфейс представляет собой концепцию ООП, которая заявляет о поведении без их реализации. Создание этих ожидаемых действий позволяет этим поведениям стать универсальными и вызываться в целом, не заботясь о специфике. Остальные подклассы для их реализации.

Классический пример ООП - это животное с двумя подклассами «Кошка и собака».

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() моего объекта Animal, и я могу быть уверен, что правильный результат будет иметь место в любом случае. Каждый отдельный подкласс знает, что ему нужно делать. В C++ воды здесь немного более грязные, но общее понятие одно и то же (читайте в ключевое слово «virtual», если вы хотите начать с этой кроличьей дыры).

Обертка

Я надеюсь, что проясняет некоторые из путаницы. Кажется, что, как вы сказали, многие разные языки имеют много разных значений для каждого из них, без сомнения, способствуют путанице. Я считаю, что если вы посмотрите дальше, вы обнаружите, что в целом это стандартные значения. Я программировал на многих языках (VB, C++, C#, Java, Paschal, PHP, Perl) в течение более 18 лет, и это определения, которые мне больше всего нравятся, полагая, что это своего рода стандарт.

Я, конечно, приветствую дальнейшее обсуждение того, что я сказал.

+2

IMHO черта выходит далеко за пределы интерфейса. Интерфейс только объявляет, какие методы могут быть найдены, но не обеспечивают реализацию. Черты также включают определение. Поэтому я вижу черту больше как своего рода * partial class *, который может быть * частичным для нескольких классов * – derM

+0

@derM Как указано в моем ответе, разные языки имеют разные значения. Я согласен с тем, что черты CAN намного превосходят просто интерфейс. Я никогда не говорил, что они не могут быть чем-то большим. Когда вы переходите к тому, что всегда означает значения, в сравнении с тем, что они иногда могут иметь в виду, вы заканчиваете с интерфейсом, являющимся общим знаменателем. Я согласен, что там есть двусмысленность, но это характер обсуждения. Не стесняйтесь публиковать свой собственный ответ, который лучше объясняет черты. – Tim