Одно из преимуществ использования идиомы


IEnumсостоит в том, что она позволяет отправителю откладывать генерирование элементов массива. Рассмотрим следующее определение метода на IDL: HRESULT GetPrimes([in] long nMin, [in] long nMax, [out] IEnumLong **ppe);
Разработчик объекта может создать специальный класс, который генерирует по требованию простые числа и реализует интерфейс
IEnumLong:
class PrimeGenerator : public IEnumLong {
LONG m_cRef;
// СОМ reference count
// счетчик ссылок СОМ
long m_nCurrentPrime;
// the cursor
// курсор long m_nMin;
// minimum prime value
// минимальное значение простого числа
long m_nMax;
// maximum prime value
// максимальное значение простого числа
public:
PrimeGenerator(long nMin, long nMax, long nCurrentPrime) : m_cRef(0), m_nMin(nMin), m_nMax(nMax),
m_nCurrentPrime(nCurrentPrime) { }
// IUnknown methods
// методы IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDHETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// IEnumLong methods
// методы IEnumLong
STDMETHODIMP Next(ULONG, long *, ULONG *);
STDMETHODIMP Skip(ULONG);
STDMETHODIMP Reset(void);
STDMETHODIMP Clone(IEnumLong **ppe);
};
Реализация генератора
Nextбудет просто порождать запрошенное количество простых чисел:
STDMETHODIMP PrimeGenerator::Next(ULONG cElems, long *prgElems, ULONG *pcFetched) {
// ensure that pcFetched is valid if cElems > 1
// удостоверяемся, что pcFetched легален, если cElems больше единицы
if (cElems > 1 && pcFetched == 0) return E_INVALIDARG;
// fill the buffer
// заполняем буфер
ULONG cFetched = 0;
while (cFetched < cElems && m_nCurrentPrime
<= m_nMax) {
prgElems[cFetched] = GetNextPrime(m_nCurrentPrime);
m_nCurrentPrime = prgElems[cFetchcd++];
} if (pcFetched)
// some callers may pass NULL
// некоторые вызывающие программы могут передавать NULL
*pcFetched = cFetched;
return cFetched == cElems ? S_OK : S_FALSE;
}
Отметим, что даже если имеются миллионы допустимых значений, одновременно в памяти будет находиться лишь малое их число.
Методу генератора
Skipнужно просто генерировать и отбрасывать запрошенное количество элементов:
STDMETHODIMP PrimeGenerator::Skip(ULONG cElems) {
ULONG cEaten = 0; while (cEaten < cElems && m_nCurrentPrime <= m_nMax) {
m_nCurrentPrime = GetNextPrime(m_nCurrentPrime);
cEaten++; }
return cEaten == cElems ? S_OK : S_FALSE;
}
Метод
Resetустанавливает курсор на начальное значение:
STDMETHODIMP PrimeGenerator::Reset(void) {
m_nCurrentPrime = m_nMin;
return S_OK;
}
а метод
Cloneсоздает новый генератор простых чисел на основе минимума, максимума и текущих значений, выданных существующим генератором:
STDMETHODIMP PrimeGenerator::Clone(IEnumLong **ppe) {
assert(ppe);
*рре = new PrimeGenerator(m_nMin, m_nMax, m_nCurrent);
if (*ppe) (*ppe)->AddRef();
return S_OK;
}
При наличии реализации
PrimeGeneratorреализация метода
GetPrimesтекущим объектом становится тривиальной:
STDMETHODIMP MyClass::GetPrimes(long nМin, long nMax, IEnumLong **ppe) {
assert(ppe);
*ppe = new PrimeGenerator (nMin, nMax, nMin);
if (*ppe) (*ppe)->AddRef();
return S_OK;
}
Большая часть этой реализации находится теперь в классе
PrimeGenerator, а не в классе объекта.
<< | >>
Источник: Дональд Бокс. Сущность технологии СОМ. Библиотека программиста. 2001

Еще по теме Одно из преимуществ использования идиомы:

  1. 4.2, НАПРАВЛЕНИЯ КОМПЛЕКСНОГО ИСПОЛЬЗОВАНИЯ ПРЕИМУЩЕСТВ БАЗОВЫХ СТРАТЕГИЙ КОНКУРЕНЦИИ
  2. Проблема «одно название, две свободные ниши
  3. И есть у всех 4 типов одно общее возражение: ДОРОГО
  4. ГЛАВА 24. ДВАДЦАТЬ ОДНО ЗОЛОТОЕ ПРАВИЛО ДЛЯ БИЗНЕСМЕНА • Рекомендации автора
  5. Врач при составлении заключения должен установить одно из следующих состояний:
  6. Преимущества кредита на образование
  7. 8.4. ПРЕИМУЩЕСТВА ФРАНЧАЙЗИНГА
  8. F. Преимущества поглощений
  9. КУРИЯ - 1) объединение мужчин-воинов в Древнем Риме, одно из древнейших подразделений римского народа.
  10. Преимущества банковских карт
  11. 35.7. ПРЕИМУЩЕСТВА И НЕДОСТАТКИ ЛИЗИНГА
  12. Преимущества системного подхода
  13. Преимущества нахождения в секторе " I "
  14. Преимущества бизнес-планирования