Зачем нам нужен декоратор в шаблоне оформления декоратора?

Функциональный подход

В эти дни все классные дети выполняют функциональное программирование ( hello React users ), поэтому я думал, что дам функциональное решение. На мой взгляд, это на самом деле намного приятнее, чем предвариантные петли for и each, которые были предложены до сих пор, и с синтаксисом ES6 он довольно изящный.

Update

теперь отличный способ сделать это под названием findIndex , который принимает функцию, возвращающую true / false на основе соответствия элемента массива (как всегда, проверьте совместимость с браузером).

var index = peoples.findIndex(function(person) {
  return person.attr1 == "john"
}

С синтаксисом ES6 вы можете написать это:

var index = peoples.findIndex(p => p.attr1 == "john")

(старый) функциональный подход

TL; DR

Если вы ищете index, где peoples[index].attr1 == "john" используют:

var index = peoples.map(function(o) { return o.attr1; }).indexOf("john");

Объяснение

Шаг 1

Используйте .map() , чтобы получить массив значений, заданных определенным ключом:

var values = object_array.map(function(o) { return o.your_key; });

Вышеприведенная строка выводит вас здесь:

var peoples = [
  { "attr1": "bob", "attr2": "pizza" },
  { "attr1": "john", "attr2": "sushi" },
  { "attr1": "larry", "attr2": "hummus" }
];

К здесь:

var values = [ "bob", "john", "larry" ];

Шаг 2

Теперь мы просто используем .indexOf() , чтобы найти индекс желаемого ключа (что, конечно, также индекс объекта, который мы ищем):

var index = values.indexOf(your_value);

Решение

Мы комбинируем все вышеперечисленное:

var index = peoples.map(function(o) { return o.attr1; }).indexOf("john");

Или, если вы предпочитаете синтаксис ES6:

var index = peoples.map((o) => o.attr1).indexOf("john");

Демонстрация:

var peoples = [
  { "attr1": "bob", "attr2": "pizza" },
  { "attr1": "john", "attr2": "sushi" },
  { "attr1": "larry", "attr2": "hummus" }
];

var index = peoples.map(function(o) { return o.attr1; }).indexOf("john");
console.log("index of 'john': " + index);

var index = peoples.map((o) => o.attr1).indexOf("larry");
console.log("index of 'larry': " + index);

var index = peoples.map(function(o) { return o.attr1; }).indexOf("fred");
console.log("index of 'fred': " + index);

var index = peoples.map((o) => o.attr2).indexOf("pizza");
console.log("index of 'pizza' in 'attr2': " + index);
13
задан nbro 2 December 2015 в 13:57
поделиться

4 ответа

Шаблон "декоратор" используется для добавления возможностей к объектам динамично (то есть, во время выполнения). Обычно объекту зафиксируют его возможности, когда Вы запишете класс. Но важный момент - то, что функциональность объекта расширяется способом, который очевиден для клиента объекта, потому что это реализует тот же интерфейс, как исходный объект делегирует ответственность перед украшенным объектом.

шаблон "декоратор" работает в сценариях, где существуют многие дополнительная функциональность, которую может иметь объект. Без шаблона "декоратор" необходимо будет создать различный класс для каждой конфигурации объектной опции. Один пример, который довольно полезен, прибывает из Главные Первые Шаблоны разработки книга O'Reilly. Это использует пример кафе, который звучит точно так же, как Starbucks.

, Таким образом, у Вас есть основной кофе с методом, любят стоимость.

public double cost(){
     return 3.45;
}

Тогда клиент может добавить сливки, которые стоят 0.35, таким образом, Вы теперь создаете класс CoffeeCream с методом расчета затрат:

public double cost(){
    return 3.80;
}

Тогда клиент может хотеть Мокко, которое стоит 0.5, и они могут хотеть Мокко со Сливками или Мокко без Сливок. Таким образом, Вы создаете классы CoffeeMochaCream и CoffeeMocha. Тогда клиент хочет густые сливки, таким образом, Вы создаете класс CoffeeCreamCream†¦ и т.д., С чем Вы заканчиваете, взрыв класса. Извините используемый плохой пример. Немного поздно, и я знаю, что это тривиально, но это действительно выражает точку.

Вместо этого можно создать абстрактный класс Объекта с абстрактным методом расчета затрат:

public abstract class Item{
    public abstract double cost();
}

И можно создать конкретный класс Кофе, который расширяет Объект:

public class Coffee extends Item{
    public double cost(){
       return 3.45;
    }
}

Тогда Вы создаете CoffeeDecorator, которые расширяют тот же интерфейс и содержат Объект.

public abstract class CoffeeDecorator extends Item{
     private Item item;
     ...
}

Тогда можно создать конкретных декораторов для каждой опции:

public class Mocha extends CoffeeDecorator{

   public double cost(){
     return item.cost() + 0.5;
   }

}

Уведомление, как декоратор не заботится, какой объект оно обертывает, пока это - Объект? Это использует стоимость () объекта объекта и просто добавляет его собственную стоимость.

public class Cream extends CoffeeDecorator{

   public double cost(){
     return item.cost() + 0.35;
   }

}

Теперь это возможно для большого количества конфигураций с этими немногими классами: например,

 Item drink = new Cream(new Mocha(new Coffee))); //Mocha with cream

или

 Item drink = new Cream(new Mocha(new Cream(new Coffee))));//Mocha with double cream

И так далее.

25
ответ дан Vincent Ramdhanie 2 December 2015 в 13:57
поделиться
  • 1
    @Matthieu, поскольку это кажется you' ре, собирающееся сделать это с --all-databases, сделайте его с мерами предосторожности. Сделайте резервное копирование и протестируйте целый алгоритм на одной базе данных сначала. – Your Common Sense 30 March 2010 в 09:50

Я не могу объяснить его лучше тогда Википедия статья.

5
ответ дан Kasper 2 December 2015 в 13:57
поделиться
  • 1
    Хорошо я просто протестировал (на одной базе данных только, чтобы быть уверенным) и этот doesn' t изменяют кодирование столбцов (они находятся все еще в " latin"). Только быть уверенным, для mysqldump, эти 3 параметра don' t нужны значения? – Matthieu Napoli 30 March 2010 в 09:56

BTW, если Вы только начинаете на шаблонах, Главная Первая книга Шаблонов разработки, феноменален . Это действительно делает понятия простыми к обзору и удостоверяется, что контрастировало и сравнило подобные шаблоны способом, который смехотворно легко понять.

3
ответ дан Spencer Kormos 2 December 2015 в 13:57
поделиться
  • 1
    @Matthieu это - на самом деле 2 параметра, насколько я понимаю. --skip-opt --set-charset говорят базе данных не добавлять пункт набора символов по умолчанию к определениям таблицы. И --skip-set-charset удаляют SET NAMES запрос из вершины дампа. Как Вы знаете о кодировании данных? utf-8 очень похож на latin1, Что он говорит относительно кодирования таблицы, если Вы работаете SHOW CREATE TABLE tablename за новой таблицей? есть ли в дампе какие-либо наборы символов? Вы называете utf8 правильно (поскольку это отличается от обычного utf-8), – Your Common Sense 30 March 2010 в 11:05

На некоторых языках (как Ruby или JavaScript) Вы могли просто добавить новую функциональность к экземпляр. Я замечаю, что Вашим вопросом является отмеченный Java, таким образом, я предполагаю, что Вы спрашиваете, почему Вы не можете сделать этого в Java. Причина состоит в том, что Java со статическим контролем типов. Экземпляр может только когда-либо иметь методы, которые класс A определяет или наследовал. Поэтому, если Вы хотите во время выполнения дать экземпляру метод, который A не определяет, тогда этот новый метод должен быть определен в различном классе.

2
ответ дан Andru Luvisi 2 December 2015 в 13:57
поделиться
  • 1
    Я действительно предпочитаю mingw выпуски, ну, в общем, всего, поскольку это делает развертывание действительно простым, когда зависимостью c-времени-выполнения является универсально доступный msvcrt.dll, а не версия Visual Studio определенное время выполнения msvcr70.dll, msvcr71.dll, msvcr80.dll, msvcr90.dll и теперь msvcr100.dll. – Chris Becke 16 October 2010 в 08:33
Другие вопросы по тегам:

Похожие вопросы: