2014-11-18 5 views
6

Я ищу примеры реального мира (с открытым исходным кодом) программ (или алгоритмов), которые изменяют конкретный класс объекта (или переменной) во время выполнения.Изменение реализации/класса во время выполнения

Примером такого поведения на Java может показаться снимок кода. Здесь LinkedList, который хорошо работает в контексте частых вставок и/или удаляет, изменен на ArrayList, который хорошо работает в контексте произвольного доступа и итерации.

List myList = new LinkedList(); 
/* Lots of inserts */ 
... 
myList = new ArrayList(myList); // 'change' into different class 
/* Lots of iteration */ 
... 

В примере Java выше изменений между LinkedList и ArrayList для ради производительности.

Однако примеры на любом языке, для любой структуры данных, с использованием любой техники * и по любой причине приветствуются.

* Техника: просто и ясно, как в примере выше, или использованием become: в SmallTalk или __class__ в Python, или ...

+0

На общем, вопрос, который просит для библиотеки здесь. Я также не могу понять цели вашего вопроса, так как ясно, что вы понимаете, в чем польза от этого, и как это можно сделать из вашего примера. – amit

+0

** Я не ищу библиотеку **, я ищу «пример кода», т. Е. Другие сценарии, в которых программисты изменяют структуру данных/классы объекта. Цель моего вопроса состоит в том, что мне нужно построить случай, что это достаточно распространенный шаблон для предоставления абстракций языка. – madewael

+1

Я часто создаю массивы динамически на фазе инициализации и использую ArrayList для этого. Тогда я знаю, что никаких дальнейших изменений не произойдет. Я преобразую его в простой старый массив, чтобы уменьшить накладные расходы памяти и немного увеличить производительность. – MrSmith42

ответ

1

Не знаю, если это уместно, но, возможно использование шпиона (частичные издевается) также подходит вашему описанию (см http://docs.mockito.googlecode.com/hg/1.9.5/org/mockito/Spy.html):

пример:

Person person = new Person(); 
person = spy(person); 
doReturn("dominiek").when(person).getName(); 

за кулисами создается подкласс и поведение класса измененную accordi ng к объявлениям о поведении пользователей.

2

Возможно, вы захотите проверить варианты использования для метода become в Smalltalk. Метод изменяет класс экземпляра во время выполнения (или для изменения всех ссылок на экземпляр для ссылки на другой экземпляр).

Become обычно используется для выращивания/сжатия коллекций, например. Словарь с большим количеством ведер, ByteArray с большим буфером и т. Д. Возможно преобразование из SmallInteger в BigIntegers (прежние ограничены по размеру, последние не являются, но намного медленнее), и программист даже не заметил (это только разумно если у вас есть переменные целые числа, поэтому это не так, как это делается в Smalltalk. Но это может быть :)

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

2

Да, посмотрите # в Smalltalk (например, MIT, лицензированный Pharo.org).

Помимо примеров, уже приведенных # например, полезно, когда вы работаете с прокси. Подумайте о прокси-объекте в рамках ORM, например, Glorp, где у вас сначала есть прокси-сервер, и когда нужен полный полный объект его можно загрузить из базы данных, и все ссылки будут переключены.

Другим примером является топливная рампа в Фаро.

1

Я только что просмотрел экземпляр этого объекта (Python) NLTK source. LazyCorpusLoader (объект, используемый для загрузки набора данных с диска) «морфирует» в самом наборе данных.Вот соответствующий раздел связанного исходного кода (создание объекта набора данных, а затем становится его):

corpus = self.__reader_cls(root, *self.__args, **self.__kwargs) 

    # This is where the magic happens! Transform ourselves into 
    # the corpus by modifying our own __dict__ and __class__ to 
    # match that of the corpus. 

    args, kwargs = self.__args, self.__kwargs 
    name, reader_cls = self.__name, self.__reader_cls 

    self.__dict__ = corpus.__dict__ 
    self.__class__ = corpus.__class__ 

Вот объяснение дано (в заголовке одного и того же файла) для этой техники:

LazyCorpusLoader - это прокси-объект, который используется для размещения объекта корпуса до загрузки корпуса. Это позволяет NLTK до создать объект для каждого корпуса, но отложить затраты, связанные с этим , с загрузкой этих корпусов до тех пор, пока они не достигнут .

Поэтому цель изменения класса во время выполнения в этом случае эмулировать ленивые вычисления.

(Edit: Так как я цитирую дословно из источника NLTK (Apache 2.0 лицензии), здесь обязательная ссылка на самой лицензии: http://www.apache.org/licenses/LICENSE-2.0)

Смежные вопросы