Шаблон разработки декоратора

После исследований я построил этот скрипт (я думаю, что в записи у меня есть набор данных, называемый «данные»):

import pandas as pd
data_2 = data.sort_values(by='timestamp', ascending=False)
data_2.index = pd.RangeIndex(len(data_2.index))
data_2['timestamp_diff'] = '?'
for i in data_2['action']: 
  index_i = int(data_2[data_2['action']==i].index[0])
  delta = 0
  for j in range(index_i,len(data_2['action'])) : 
    if 'mouse' in data_2['action'][j] and 'pressed' in data_2['action'][j]:
      delta+=1
      if delta ==data_2['count'][index_i]:
        print(data_2['count'][index_i])
        data_2['timestamp_diff'][index_i] = round(data_2['timestamp'][index_i] - data_2['timestamp'][j],3)

    else :
      delta = delta

data = data_2.sort_values(by='timestamp')
data.index = pd.RangeIndex(len(data.index))
data
5
задан Ryan 3 February 2009 в 00:46
поделиться

2 ответа

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

class Base {

  function foo() {
    return "foo";
  }

  function bar() {
    return "bar";
  }

}

// Not what we think of as a Decorator,
// really just a subclass.
class Decorator extends Base {

  // foo() inherits behavior from parent Base class 

  function bar() {
    return parent::bar() . "!"; // add something
  }

}

Класс Декоратора не расширяет базовый класс своего "украшенного" класса. Это - другой тип, который имеет членский объект украшенного класса. Таким образом это должно реализовать тот же интерфейс, если только назвать соответствующий метод украшенного объекта.

class Decorator { // extends nothing
  protected $base;

  function __construct(Base $base) {
    $this->base = $base;
  }

  function foo() {
    return $base->foo();
  }

  function bar() {
    return $base->foo() . "!"; // add something
  }

}

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

interface IBase {
  function foo();
  function bar();
}

class Base implements IBase {
  . . .
}

class Decorator implements IBase {
  . . .
}

Ре: комментарий Dahan @Yossi: Я вижу неоднозначность в статье Википедии, но если Вы читаете тщательно, она действительно говорит, что украшаемый компонент является полем в объекте декоратора, и что компонент передается как аргумент конструктору декоратора. Это отличается от наследования.

Хотя в статье Википедии действительно говорится, что декоратор наследовался компоненту, необходимо думать об этом как о реализации интерфейса, когда я показал в примере PHP выше. Декоратор все еще должен проксировать для объекта компонента, который это не было бы, если это наследовалось. Это позволяет декоратору украшать объект любого класса, который реализует тот интерфейс.

Вот некоторые выборки из "Шаблонов разработки: Элементы Допускающего повторное использование Объектно-ориентированного программного обеспечения" Гаммой, Рулем, Johnson и Vlissides:

Декоратор

Намерение

Присоедините дополнительные обязанности перед объектом динамично. Декораторы обеспечивают гибкую альтернативу разделению на подклассы для расширения функциональности.

Мотивация

... Декоратор соответствует интерфейсу компонента, который он украшает так, чтобы его присутствие было очевидно для клиентов компонента.

Участники

  • Декоратор поддерживает ссылку на объект Компонента и определяет интерфейс, который соответствует интерфейсу Компонента.
15
ответ дан 18 December 2019 в 09:10
поделиться

Я задавался вопросом, почему шаблон "декоратор" предлагает, чтобы декоратор реализовал все открытые методы компонента, которого он украшает?

Декоратор должен быть понижением замены для компонента, который она украшает с дополнительной функциональностью ("художественное оформление"). Это может только произойти, если это полностью реализует интерфейс компонента.

Класс декоратора не может только использоваться для обеспечения дополнительных поведений и затем конкретного компонента (который передается в него) просто использоваться для вызова всего остального?

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

И во-вторых, что, если конкретный компонент Вы хотите украсить, не имеет базового класса, из которого может также произойти абстрактный декоратор?

Декораторы обычно наследовали класс компонента, который они украшают, не основа компонента.

3
ответ дан 18 December 2019 в 09:10
поделиться