Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

GrandM-Patterns_in_Java

.pdf
Скачиваний:
95
Добавлен:
14.03.2016
Размер:
8.88 Mб
Скачать

Facade _ 247

Adapter. Шаблон Adapter позволяет клиентским классам считать единствен­ ный объект, не реализующий некоторый интерфейс, объектом, действительно реализующим этот интерфейс. Шаблон Facade позволяет клиентским классам рассматривать группу объектов как единственный объект, реализующий опре­ деленный интерфейс.

Pore FаЬriсаtiоп. Проект класса фасада представляет собой случай применения

шаблона Pure Fabrication, описанного в книге [Grand99].

Этот шаблон ранее был описан в работе [GoF95].

СИНОПСИС

Если экземпляры класса, содержащие одинаковую информацию, MOryr Исполь­

зоваться как взаимозаменяемыес , то шаблон F1yweight позволяет программе из­ бежать издержек, связанных созданием множества экземпляров, содержащих одинаковую информацию, применяя механизм совместного использования од­ ного экземпляра.

КОНТЕКСТ

Предположим, создается текстовый процессор. На рис. 7.13 представлена диа­ грамма классов, описывающая некоторые основные классы, которые можно

использовать для представления документа:

DocumentElement -исходный суперкласс для всех классов, используемых для представления документа; все подклассы класса DocumentElement на­

следуют методы для записи и считывания своих шрифтов;

экземпляр класса DocChar представляет каждый символ документа; DocumentContainer - суперкласс для контейнерных классов Document,

Page, Paragraph и LineOfText.

DocumentElement

0..*

 

getFontO. . .

: Font

 

 

 

 

 

 

 

 

 

 

 

 

 

setFont(font:Font)

 

 

 

 

 

 

 

 

 

 

 

getParentO :DocumentContainer

 

 

 

 

 

 

setParent(parent:DocumentContainer)

1 Н

 

 

 

 

I

 

t

 

 

 

 

I

 

 

 

DocChar

I

 

 

 

DocumentContainer

 

 

 

 

 

getChiLd(index:int) : DocumentElement

 

 

 

 

 

 

 

 

 

 

 

 

 

 

addChiLd(chiLd:DocumentElement)

 

 

 

 

 

 

 

 

 

removeChiLd(chiLd:DocumentELement)

 

I

J

 

 

 

 

 

 

 

 

 

 

 

 

 

Document

 

 

 

 

Page

 

Paragraph

 

LineOfТext

 

 

 

 

Рис. 7.13. Классы представления документа

 

 

 

 

 

 

 

 

Flyweight 8 249

Можно задать шрифт для каждого символа, вызывая метод s e t Font объекта

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

тейнер использует шрифт своего контейнера и т.д.

ОДИН документ, состоящий из нескольких страниц, может содержать десятки

Иобъектов Paragraph, которые содержат несколько сотен объектов LineOfText

тысячи или десятки тысяч объектов DocChar. Очевидно, что результатом ис­

мапользования такого проекта будет программа, требующая значительного объе­

памяти для хранения символов.

ныеСушествует возможность избежать больших затрат памяти на эти многочислен­ та объекты DocChar, имея только один экземпляр каждого отдельного объек­ CocChar. Изображенные нарис. 7. 1 3 классы применяют объект DocChar для

представления каждого символа документа. Чтобы представить фразу «She saw

her father.,

объект LineOfText использует объекты DocChar (рис. 7. 14).

 

 

 

 

 

 

 

 

 

 

 

 

 

I

 

 

 

 

 

 

;Li!! OfТ !!t

 

 

 

 

I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

S

h

е

 

 

 

 

 

 

 

s

а

w

 

h

е

r

 

f

а

 

t

h

е

'4

 

 

 

 

 

 

 

 

I

 

 

 

I

 

S:DocChar

 

 

г

-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

r2:DocC ar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

 

 

bl:DQ,Char

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

e3:DocCh r

I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

--1

h3:DocChar I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

г---

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

--1

 

 

 

 

 

 

 

 

 

 

I

el:Do,Char

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

lblankl:DocCharJ

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'---itl:DocChar I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

---

j a2;Dg,thj!r I

 

 

 

 

 

 

 

 

 

 

 

 

I

 

sl:DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

 

 

j!l;DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

fl:DocChj!r

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I!l.i!пkЭ;DQ,Сh"r l

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

 

 

wl:DQ,Chj!r

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I b!i!nk2:DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

rl:DocChar

 

 

I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

e2;DQ,Char I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I h2:Do Char

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис.

7.14.

 

Объекты символов, не являющиеся совместно используемыми

 

От

что

в строке несколько раз встречаются символы «h» , «е»

,

 

«

 

»

(про­

метим,

 

 

бел), «а» и (ф). В документе все символы обычно встречаются много раз.

Можно

1/РеЯдорганизовать объекты таким образом, чтобы один объект DocChar представ-

все случаи появления одного и того же символа (рис. 7. 1 5).

250

 

Глава 7.

Структурные шаблоны проектирования

е r I

 

 

 

 

 

 

 

 

 

 

I s h е

 

5 а w

 

h е

r

 

f а t h

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

:LinеОfТgЮ;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I S:DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

l-1

r:Doj;Char

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

 

 

г---

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

h:DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

 

e:DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I blank:DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

у

 

I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

t:Doj;Char

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

II

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

s:DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

jI:Doj;Chi!r

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

JI

 

 

 

 

 

 

 

 

I

w:DocChar

IL

 

 

 

 

 

 

 

 

 

f:DocChar

I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 7.15.

Совместно используемые объекты символов

 

 

 

 

Чтобы быть совместно используемыми, объекты DocChar не должны обладать какими-либо внутренними атрибутами, которые не являются общими для лю­ бого места, на которое ссылается объект. Внутренний атрибут - это атрибут, значение которого хранится вместе с объектом. Он отличается от внешнего ат­ рибута, значение которого хранится вне своего объекта.

Организация классов, представленная на рис. 7. 1 3, описывает класс DocChar,

экземпляры которого могут иметь внутренний атрибут шрифта. Те объекты DocChar, которые не имеют храняшегося внутри них шрифта, используют

шрифт своего абзаца.

Чтобы совместно использовать объекты DocChar, классы должны быть реорга­ низованы таким образом, чтобы объекты DocChar, имеющие свои собственные

шрифты, хранили бы их в виде внешних атрибутов. На рис. 7. 16 представлен

также класс CharacterContext, экземпляры которого сохраняют внешние ат­ рибуты для целого ряда символов.

В этой структуре класс DocCharFactory отвечает за предоставление объекта

DocChar, определяющего данный символ. Если задавать для представленИЯ

один и тот же символ, метод getDocChar объекта DocCharFactory всегда будет

возвращать один и тот же объект DocChar. Кроме того, класс DocumentContaine!, а не класс DocumentElement, определяет методы по работе со шрифтом. все

конкретные классы, за исключением DocChar, являются подклассами класса DосumепtСолtаiпеr. Это означает, что класс DocChar не имеет BHyтpeHHeсиМfO­

атрибута шрифта. Если пользователь захочет связать шрифт с каким-либо волом или набором символов, то программа создаст объект CharacterConte}(t

(рис. 7. 1 7).

IDocumentElement

1.

Flyweight - 251

0••*

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

t 1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0 *

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

DocumentContainer

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

 

 

 

 

 

 

 

getFontO : Font

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

"'

Создает и управляет

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

••

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

setFont{font:Font)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1 ..

*

 

 

 

 

 

 

 

 

 

многократным

 

 

 

 

 

 

 

 

 

 

getParentO :DocumentContainer

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

использованием

 

 

 

 

 

 

 

setParent{parent:DocumentContainer)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

( )

 

 

 

 

 

getChild{index:int) :DocumentElement

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

addChild{chiLd:DocumentELement)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

DocCharFactory

 

 

 

 

 

 

 

 

 

 

removeChild{...

child:DocumentElement)

 

 

 

 

 

 

 

 

It

 

 

 

 

 

getDocChar{с:char):DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

 

 

 

 

 

 

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

 

CharacterContext

 

I

 

 

Document

"

 

 

 

 

 

 

Page

 

 

"

 

 

 

Paragraph

"

 

LineOfТext

I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 7.16.

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

s

 

 

 

 

 

 

а w

 

 

:Lin!:OfТext

r

 

 

 

f

 

 

 

t

 

h е

 

r

 

I

 

 

 

 

 

 

I

 

 

 

 

 

 

 

 

 

 

 

 

h е

 

5

 

 

h е

 

 

 

а

 

 

 

 

 

 

 

 

I

 

 

 

S:DocChjJr

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

--1

r:DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

г--

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

l

h:DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

 

!::DO!;Char

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I blank:DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ч

t:DocChar

 

I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

11

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I s:DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

a:DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

 

w:DocChar

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

f:DocChar

I

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

:Chara!;terContext

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

font:Font .. italic-Serif-12

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

h

 

...

 

 

e l

 

 

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 7.17. Шрифт в объекте CharacterContext

 

 

 

 

 

 

 

 

 

 

 

 

252 Глава 7. Структурные шаблоны проектирования

МОТИВЫ

©Есть приложение, которое использует большое количество одинаковых

объектов.

©Необходимо уменьшить значительные затраты памяти на поддержку боль­ шого количества похожих объектов.

©Программа не полагается на уникальность объектов любых объектов, кото­ рые она, по желанию разработчика, должна совместно использовать. Если

программа применяет различные объекты в разных контекстах, то сущесг­ вует возможность различать контексты, используя уникальность объектотво. Если различные контексты совместно используют одни и те же объекты, эти контексты уже нельзя отличать при помощи уникальности объектов.

©Представление похожих вещей похожими объектами требует большего объ­ ема памяти, чем представление похожих вещей при помощи одного и тогоже же объекта. Чем больше вещей могут быть представлены одним и тем объектом, тем значительнее экономия памяти.

РЕШЕНИЕ Д1IЯ

На рис. 7. 1 8 представлена основная организация классов шаблона Flyweight.

Опишем роли, которые исполняют эти классы.

AbstractF1yweight. Класс AbstractFlywei ght представляет собой суперкласс

для всех других классов-приспособленцев. Он определяет общие для клас­ сов-приспособленuев методы. Эти методы нуждаются в доступе к информации о внешнем состоянии и обычно получают его с помощью параметров.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1 II

CLient

1 1

h-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

AbstractFlyweight

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

орегаооn(extrinsicState: object)

 

 

 

 

 

....

Создает и управляет

использует....

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Использует

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

использует....

 

 

использованием

 

 

 

 

 

0..*

 

 

 

 

 

 

 

 

 

 

 

0-.'

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

 

 

 

 

 

 

 

 

 

0..*

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ght

 

RyweightFactory

 

 

 

 

 

SharedConcreteFLyweightI I

 

 

UnsharedConcreteFlywei

 

О

 

 

 

 

 

 

I

-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

getFlyweight(attribute:object)

 

 

 

operation(extrinsicState:object)

 

operation(extrinsicState:objed)

 

 

 

 

 

 

 

 

 

 

..*

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1 1

 

 

 

 

Рис. 7.18. Шаблон Flyweight

0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(оздает

 

 

 

 

т

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Flyweight 253

SharedConcreteFlyweight. Экземпляры классов в этой роли являются объектами

10общего использования. Если они содержат какое-либо внутреннее состояние,

оно должно быть общим для всех представляемых ими сущностей. Напри­ мер, совместно используемые объекты DocChar, описанные в примере раздела «Контекст.>, представляют символ как свое внутреннее состояние.

UnsharedConcreteFIyweight. Экземпляры классов, участвующих в роли Unshared­ concreteFlyweight,tle не являются совместно используемыми. Шаблон F1yweight требует от объектов быть совместно используемыми. Он просто разрешает совместное использование объектов. Если сушествуют объекты, которые не ис­

топ льзуются совместно и являются экземплярами класса AbstractFl yweight,

они не будут экземплярами SharedConcreteFl yweight подклассов класса

AbstractFlyweight .

}1yweightFactory. Экземпляры классов FlyweightFactory предоставляют эк­ земпляры класса AbstractFlywei ght клиентским объектам. Когда клиентский объект запрашивает объект FlyweightFactory с целью предоставления экземп­ ляра класса UnsharedConcreteFlyweight, тот просто создает этот экземпляр. Однако, когда клиентский объект обращается к объекту FlyweightFactory за предоставлением экземпляра класса SharedConcreteFlyweight, тот сначала проверяет, не был ли похожий объект создан ранее. Если такой объект уже бьVI сВоздан, то он предоставляет клиентскому объекту ранее созданный объект.

противном случае он создает новый объект и предоставляет его клиенту.

Client. Экземпляры классов Cl ient - это объекты, использующие объекты­ приспособленцы.

ryrЕсли в роли SharedConcreteFlyweight выступает только один класс, то мо­ не понадобиться классы, исполняющие роль AbstractFlyweight или

UnsharedConcreteFlyweight.

РЕАЛИЗАЦИЯ

Между количеством атрибутов, которые создают внешними, и количеством

объектов-приспособленцев, необходимых на стадии выполнения, существует некоторый компромисс. Чем больше атрибутов создают внешними, тем меньше ПОтребуется объектов-приспособленцев. Чем больше атрибутов создают внутрен­ НИми, тем меньше времени потратят объекты для доступа к своим атрибутам.

Рассмо рим пример представления документа. Если пользователь, например,

8ыдляетT несколько символов курсивом, то программа создаст отдельный объ­

el(T

CharacterContext, который будет содержать внешний атрибут шрифта

Ч1I1j

тех

объектов

DocCha r,

А

 

 

которые представляют эти символы. льтернатив­

ый вариант ПОзволяет атрибуту шрифта быть внутренним атрибутом объектов

"OcChar. Если атрибут шрифта является внутренним, то объекты DocChar бу­

затрачивать на доступ к своему атрибуту шрифта меньше времени. Если ат­

буТу

шрифта разрешено быть внутренним, то это означает также, что про­

tvaMMe

потребуется отдельный объект DocChar для представления каждой

rОМбинации «символ - шрифт.>.

7.16

254 Глава 7. Структурные шаблоны проектиравания

СЛЕДСТВИЯ

© Применяя объекты-приспособленцы совместного использования, можно значительно уменьшить количество объектов, находящихся в памяти.

® Шаблон Flyweight усложняет просрамму. Основными источниками допол­ нительной сложности являются объекты-приспособленцы со своими внеш_ ними состояниями, а также управление многократным использованием объектов-приспособленцев.

® Шаблон Ayweight может привести к увеличению времени работы просраммЪJ так как доступ объекта к внешнему состоянию требует больших усилий, че доступ к внутреннему состоянию.

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

Шаблон Ayweight делает это невозможным, так как с его помощью множеСТВо сущностей представляется в конечном счете одним и тем же объектом.

® Совместно используемые объекты-приспособленцы не могут содержать ссылок на родителей.

® Из-за сложности, связанной с использованием шаблона Ayweight, и orpa· ничений, накладываемых им на организацию классов, следует рассматри· вать шаблон Ayweight как оптимизацию, применяемую после разработки остальной части проекта.

ПРИМЕНЕНИЕ В JAVA API

Java использует шаблон Flyweight для управления объектами Stri ng, которые применяются для представления строковых литералов. Если в проrpамметуимже­

ется более одного строковоro литерала и эти литералы содержат одну и

последовательность символов, то Java использует один и тот же объект String для представления всех этих литералов.

Метод intern класса String отвечает за управление объектами String, коТО'

рые используются для представления строковых литералов.

ПРИМЕР КОДА

Приведем код, который реализуетдиаrpамму классов, изображенную на рис.

Исходный текст некоторых классов не представляет интереса с точки зреtfllЯ шаблона Flyweight, поэтому коды таких классов опущены, например, класса

DocurnentElernent. Класс DocurnentConta iner определяет некоторые методЬ1.

которые наследуют все контейнерные классы, применяемые для представлеНlIЯ документа:

aЬstract class DocumentContainer extends DocumentElement

1 1 Коллекция потомков этого= объекта . private Vector children new Vector () ;

Flyweight - 255

// Это шрифт , связанный с дaHHЬ объектом .

//Если переменная шрифта - nu l l , то шрифт этого объекта

//будет наследоваться от контейнера этого объекта

через иерархию контейнеров .//

private Font font;

/ * *

 

DocumentContainer parent; // Контейнер этого объекта .

*/

index .

* Возвращает потомка этого объекта , под номером

puыlcc DocumentElement getChild (int index) {

 

return (DocumentElement) children . elementAt(index) ;

/ * *

 

} / / getChi ld ( int)

 

*/

объекта .

* Делаем данный DocumentElement потомком этого

puыlcc synchronized void addChild (DocumentElement child) {

 

synchronized (child) {

 

 

 

 

 

children. addElement (child) ;

 

 

 

 

 

if

(child instanceof DocumentContainer)

 

 

 

/ /

« DocumentContainer) child) . parent

=

this i

 

}

s ynchronized

 

 

/ * *

 

addChild ( DocumentElement)

 

 

 

//

 

 

*

/

Делаем так, чтобы данный DocumentElement Н Е БЫЛ потомком

*

этого объекта .

 

 

*

 

 

 

puыlcc

synchronized void removeChild (DocumentElement child) {

 

synchronized (child)

{

 

 

if (child instanceof DocumentContainer

 

 

&& this == «

DocumentContainer) child) . parent)

 

« DocumentContainer) child) . parent =

null;

 

children . removeElement (child) ;

 

 

// synchronized

 

 

/ * *

 

 

 

// removeCh i ld ( DocumentElement )

 

*

Возвращает родителя

этого объекта или null ( если у него нет

*

родителя ) .

 

 

256 Глава 7. Структурные шаблоны праектиравания

*/

 

 

 

public DocumentContainer getParent () {

 

return parent;

 

 

 

/ / getParent ( )

 

 

/ * *

 

 

 

*

Возвращает шрифт ,

связанный с этим объектом .

Если нет шрифта ,

связанного с этим объектом, то возвращает

*

шрифт его родителя . Если нет щрифта, связанного

*

с родителем этого объекта ,

то возвращает nul l .

*/

 

 

 

public Font getFont ()

 

 

if (font ! = null)

 

 

 

return font;

 

 

 

else if (parent != null)

 

 

return parent . getFont () ;

 

 

else

 

 

 

 

return null;

 

 

}

/ / getFont ( )

 

 

 

/**

 

 

 

*

Связываем

шрифт

с этим объектом .

* /

 

 

 

public void setFont (Font font)

{

 

this . font =

font;

 

 

}// setFont (Font)

}// c l a s s DocumentContainer

Методы, описанные в классе DocumentContainer, управляют состоянием всех

контейнерных классов документа, включая класс CharacterContext. ИспоЛЬ­

зуя эти унаследованные методы, класс CharacterContext способен управляТЬие­

внешним состоянием объектов DocChar, даже если он не объявлял с этой

лью какие-либо собственные методы. Приведем код класса DocChar, которыЙ

представляет символы документа:

class DocChar extends DocumentElement private char character;

DocChar (char с) { character = с ;

// Cons t ructor ( char)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]