|
Visitor
В предишния урок видяхме как най-лесно да свържеме отделни елементи в комплексни структури от данни (пример за такава комплексна структура е например една файлова система, в която всяка папка може да съдържа подпапки и файлове, или навигацията на една web-страница, в която един елемент от менюто може да е както самостоятелен линк, така и контейнер за други линкове ). В нашите програми често ни се налага да боравим с такъв тип структури и да ги манипулираме по най-разнообразни начини: да ги претърсваме за някакъв оределен елемент, да ги показваме на екрана, записваме на тръвдия диск и тн. Да речеме, че искаме "програмата" от предишния пример да изпечатва в един файл структурата на менютата.Най-елементарно това може да стане като добавиме по един метод във всеки от класовете, който да изписва себе си в даден изходен поток OutputStream (по подобен начин както изписва себе си в метода toString()). Както може би сами се сещате, това е най-голямата грешка която можете да направите в случая. Представете си например, че след известно време ви потрябва да представите менюто не като HTML , ами XML -форматиран файл, или път ще искате да го запишете в накоя база данни, и какво ли още не. При това положение, кода на класовете Link, LinkGroup и ImgLink ще се раздуе от методи, които нямат нищо общо със семантиката на класовете, ще го направят неразбираем за четене и труден за потдръжка а да не говорим че ще бъде тясно специализиран за нуждите на дадената програма, която го ползва и неговото внедряване в други програми невъзможно. Едно от най-големте прдизвикателства към програмиста е да запизи своите обекти чисти от неприсъща за тях логика.Едно меню знае как е структурирамо, кои са неговите подменюта, но няма нужда да знае как да се запамети върху твърдия диск, тъи като това не е присъщо за него. Някои умни глави преди време са се сблъскали с този проблем и са измислили модела Visitor, който е гениален по своята простота, позволява да си държите обектите прегледни и чисти. Един Visitor се състои от един интерфейс, който декларира методи които ще се извикват при обхождането на данните.Обикновено интерфейса се нарича Visitor а методите са visit(Component c), visitStarted(Container c), visitEnded(Conteiner c), какти о поне един конкретен клас, който да го имплементира. Базовият клас на Composite дефинира един метод наречен accept(Visitor visitor), в който извиква метода visit(this) на Visitor-а и предава себе си като аргумент. В Container класа изглежда малко по-сложно, тъй като той трябва да предекларира метода accept(Visitor visitor) , на базовия клас. В метода visit(Visitor visitor) Container класа извиква първо метода visitStarted(this), след това извиква метода accept(visitor) на всички свои елементи и накрая извиква метода visitEndet(this) на Visitor-a. Съгласен съм, че звучи малко объркано затова нека да онагледиме обясненото до тук с едни прост пример, които ще изкара на конзилата едно просто XML-дърво със структурата на нашето меню от предишния урок.Visitor
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||









