1 / 44

Паттерн Адаптер

Паттерн Адаптер. (Adapter). Определение. Определение. Адаптер — структурный шаблон проектирования, предназначенный для организации использования функций объекта, нежелательного для модификации, через уже существующий интерфейс. Реализация.  адаптер класса (множественное наследование.

marge
Download Presentation

Паттерн Адаптер

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ПаттернАдаптер (Adapter)

  2. Определение Определение Адаптер—структурныйшаблонпроектирования, предназначенныйдляорганизациииспользования функцийобъекта,нежелательногодля модификации,черезужесуществующий интерфейс. Реализация адаптеркласса(множественноенаследование классовилиинтерфейсов); адаптеробъекта(композиция).

  3. Мотивация Мотивация Частоменяющиесяверсииилиреализации(сторонних) библиотечныхклассов Возможно,чтобиблиотека,которуювыиспользуете,часто изменяетсяиливыпланируетепереходнадругуюреализацию требуемойфункциональности(другуюбиблиотеку). Недоступныйдлямодификациикодснеподходящиминтерфейсом Возможно,чтоопределеннойчастинашегокодатребуетсядругой интерфейсотобъекта,модификациякоторогонежелательнаили невозможна. Несуществующийещѐкодсизвестнойнаперед функциональностью Возможно,чтокод,обеспечивающийтребуемую функциональность,ещѐненаписан(стороннимиразработчиками), однакообщиепринципыегоработыужеясны.   

  4. Плюсы Плюсы: Инкапсуляцияреализациивнешнихклассов (компонентов,библиотек).Такимобразом, системастановитсянезависимойот интерфейсавнешнихклассов. Переходнаиспользованиедругих (несовместимыхпоинтерфейсу)внешних классовнетребуетпеределкисамой системы,достаточнозаменитьреализацию соответствующихадаптеров. 

  5. Адаптеркласса

  6. Адаптеробъекта

  7. Участники Target—целевой:определяетзависящийот предметнойобластиинтерфейс,которым пользуетсяClient. Client—клиент:вступаетвовзаимоотношенияс объектами,удовлетворяющимиинтерфейсуTarget. Adaptee—адаптируемый:определяет существующийинтерфейс,которыйнуждаетсяв адаптации. Adapter—адаптер:адаптируетинтерфейс AdapteeкинтерфейсуTarget.

  8. Пример№1 Пустьестьунаследованныйкласспрямоугольника: typedefintCoordinate; classLegacyRectangle { public: LegacyRectangle(Coordinatex1,Coordinatey1,Coordinatex2,Coordinatey2) :x1_(x1),x2_(x2_),y1_(y1),y2_(y2) { std::cout<<"LegacyRectangle: create.("<<x1_<<","<<y1_<< ")=>("<<x2_<<","<<y2_<<")"<<std::endl; } voidOldDraw(){ std::cout<<"LegacyRectangle: OldDraw. ("<<x1_<<","<<y1_<< ")=>("<<x2_<<","<<y2_<<")"<<std::endl; } private: Coordinatex1_,y1_,x2_,y2_; };

  9. Пример№1 Ожидаемыйклиентоминтерфейсвыглядит следующимобразом: classRectangle { public: virtualvoidDraw()=0; };

  10. Пример№1 КлассадаптеранаследуетинтерфейсRectangleи реализациюLegacyRectangle: typedefintDimension; classRectangleAdapter:publicRectangle,privateLegacyRectangle { public: RectangleAdapter(Coordinatex,Coordinatey,Dimensionw,Dimensionh) :LegacyRectangle(x,y,x+w,y+h) { std::cout<<"RectangleAdapter:create.("<<x<<","<<y<< "),width="<<w<<",height="<<h<<std::endl; } virtualvoidDraw() { std::cout<<"RectangleAdapter:draw."<<std::endl; OldDraw(); } };

  11. Пример№2 ПустьестьклассSSH-подключения,который используетсявсистеме: publicabstractclassSSHTunnel { publicabstractintLocalPort {get;set;} publicabstractstringRemoteHost {get;set;} publicabstractintRemotePort {get;set;} publicabstractvoidOpen(); publicabstractvoidClose(); }

  12. Пример№2 АдаптируембиблиотечныйклассElSimpleSSHClientизнабора SecureBlackBoxктребуемомуинтерфейсу: publicclassSecureBlackboxSSHTunnelAdapter:SSHTunnel{ ElSimpleSSHClientsshClient; publicSecureBlackboxSSHTunnelAdapter(){ sshClient=newElSimpleSSHClient(); sshClient.UseInternalSocket=true; } publicoverridevoidOpen() { sshClient.Open(); } publicoverridevoidClose() { sshClient.Close(); } }

  13. Пример№2 publicclassSecureBlackboxSSHTunnelAdapter:SSHTunnel { publicoverrideintLocalPort{ get{returnsshClient.SocksPort;} set{sshClient.SocksPort=value;} } publicoverridestringRemoteHost{ get{returnsshClient.Address;} set{sshClient.Address=value;} } publicoverrideintRemotePort { get{returnsshClient.Port;} set{sshClient.Port=value;} } }

  14. Паттерны проектирования

  15. Чтотакоепаттерныпроектирования КристоферАлександр:«шаблонописываетзадачу,котораясноваиснова возникаетвработе,атакжепринципеерешения,такимобразом,чтоэто решениеможноиспользоватьмногократнобезизменений». Шаблоныпроектирования(паттерн,pattern)―этоэффективные способырешенияхарактерныхзадачпроектирования,вчастности проектированиякомпьютерныхпрограмм.Паттерннеявляется законченнымобразцомпроекта,которыйможетбытьпрямопреобразован вкод,скорееэтоописаниеилиобразецдлятого,какрешитьзадачу, такимобразом,чтобыэтоможнобылоиспользоватьвразличных ситуациях. Шаблонпроектирования―описаниевзаимодействияобъектови классов,адаптированныхдлярешенияобщейзадачипроектированияв конкретномконтексте. Алгоритмынеявляютсяшаблонами,таккаконирешаютзадачи вычисления,анепроектирования. Каркасыприложенийнеявляютсяшаблонами,таккакони относятсяккакой-токонкретнойпредметнойобласти состоятизнесколькихшаблонов.  

  16. ПричиныиспользованияиклассификацияПричиныиспользованияиклассификация Возможностьмногократногоиспользования Использованиечужогоопытавзаменсамостоятельногоизобретения велосипеда Единаятерминология Выделениеуровняабстракции     Порождающиешаблоны(Creationalpatterns)абстрагируютпроцесс инстанцирования.Онипозволяютсделатьсистемунезависимойот способасоздания,композицииипредставленияобъектов. Структурныепаттерны(Structuralpatterns)решаютвопросотом,какиз ужеимеющихсяклассовиобъектовоптимальнополучитьболеекрупные структурыиобразования. Паттерныповедения(Behavioralpatterns)отвечаютзаинкапсуляцию алгоритмовираспределениеобязанностеймеждуобъектами. Такжевыделяютпаттерныпараллельнойобработки(concurrencypatterns), системныепаттерны(systempatterns),интеграционныепаттерны(integral patterns)ит.д.

  17. Изображениекласса Защищенныйметод Открытыйметод Закрытыйметод

  18. Отношениеассоциации Покупательимеетмногосчѐтов: Классприложенияиспользуетклассподключения:

  19. Отношениеобобщения Классокружностиявляетсянаследникомклассафигуры:

  20. Отношениеагрегации Класспокупателясодержитссылкунаколлекцию заказоввполеOrders(отношениеодинкомногим): Классзаказасодержитссылкунапродуктвполе Product(отношениеодинкодному):

  21. Схемаописанияпаттерна Определение Содержиткраткийответнавопросы:каковыфункциии назначениепаттерна. Мотивация Описаниеситуаций,вкоторыхможноиспользоватьданный паттерн. Плюсы Преимущества,получаемыеприрешениизадачис использованиемданногопаттерна. Диаграммаклассов Участники Описаниеклассов,задействованныхвданномпаттерне проектирования,иихфункции. Пример(ы)кода      

  22. ПаттернОдиночка (Singleton)

  23. Определениеимотивация Определение Одиночка—порождающийпаттерн,который гарантирует,чтоуклассаестьтолькоодин экземпляр,ипредоставляеткнемуглобальную точкудоступа. Мотивация Долженбытьровноодинэкземплярнекоторого класса,легкодоступныйвсемклиентам. Единственныйэкземплярдолженрасширяться путемпорожденияподклассов,иклиентамнужно иметьвозможностьработатьсрасширенным экземпляромбезмодификациисвоегокода.

  24. Плюсы Контролируемыйдоступкединственномуэкземпляру. ПосколькуклассSingletonинкапсулируетсвойединственный экземпляр,онполностьюконтролируетто,какикогдаклиенты получаютдоступкнему. Уменьшениечислаимен. Паттернпозволяетизбежатьзасоренияпространстваимен глобальнымипеременными,вкоторыххранятсяуникальные экземпляры. Допускаетуточнениеопераций. Можнопараметризироватьприложениеэкземпляромтогокласса, которыйнеобходимвовремявыполнения. Допускаетпеременноечислоэкземпляров. Большаягибкость,чемуоперацийкласса(статическихметодов).     

  25. Паттернодиночка.Диаграмма

  26. Участники Участники Singleton―определяетоперацию полученияэкземпляра―статический метод,которыйпозволяетклиентам получатьдоступкединственному экземпляру.Можетнестиответственность засозданиесобственногоуникального экземпляра.

  27. Пример№1 Стандартнаяреализация: publicclassSingleton { protectedSingleton(){} privatestaticSingletoninstance; publicstaticSingletonInstance { get { if(instance==null) instance=newSingleton(); returninstance; } } }

  28. Пример№2 РеализациясиспользованиемшаблоноввязыкеC#: publicclassSingleton<T> whereT:class,new() //Tявляетсяклассом,имеетконструкторбезпараметров { protectedSingleton(){} privatestaticTinstance; publicstaticTInstance{ get{ if(instance==null) instance=newT(); returninstance; } } }

  29. Пример№2 Данныйшаблонныйклассиспользуетсяследующим образом: publicclassTestClass:Singleton<TestClass> { publicTestClass(){} publicvoidOperation() { //implementation } }

  30. Пример№2` publicclassSingleton<T>whereT:class{ // Защищенныйконструкторпоумолчаниюнеобходимдлятого,чтобы //предотвратитьсозданиеэкземпляраклассаSingleton protectedSingleton(){} //Фабрикаиспользуетсядляотложеннойинициализацииэкземпляракласса privatesealedclassSingletonCreator<S>whereS:class{ //ИспользуетсяReflectionдлясозданияэкземпляра //классабезпубличногоконструктора privatestaticreadonlySinstance=(S)typeof(S).GetConstructor( BindingFlags.Instance|BindingFlags.NonPublic, null,newType[0], newParameterModifier[0]).Invoke(null); publicstaticSCreatorInstance{ get{returninstance;} } } publicstaticTInstance{ get{returnSingletonCreator<T>.CreatorInstance;} } }

  31. Пример№3 Принеобходимостииспользованиянаследниковкласса одиночкинаиболеегибкимметодомявляется использованиереестраодиночек. publicclassRegSingleton{ privatestaticRegSingletoninstance; privatestaticDictionary<string,RegSingleton>registry= newDictionary<string,RegSingleton>(); protectedRegSingleton(){} publicstaticvoidRegister(Stringname,RegSingletoninstance) { registry.Add(name,instance); } protectedstaticRegSingletonLookup(Stringname) { returnregistry[name]; } }

  32. Пример№3 Теперьинформациюотом,какойименноэкземпляр одиночкииспользовать,можноопределитьнаэтапе работыпрограммы: publicclassRegSingleton { privatestaticRegSingletoninstance; publicstaticRegSingletonInstance() { if(instance==null) { stringname=System.GetProperty("SINGLETON_NAME"); instance=RegSingleton.Lookup(name); } returninstance; } }

  33. Пример№3 Основнаяпроблемаиспользованияреестраодиночек состоитврегистрацииэкземпляроводиночек. Например,вязыкеC#длярегистрациииспользуется статическийконструктор. publicclassSingleton:RegSingleton { staticSingleton() { newSingleton(); } protectedSingleton() { RegSingleton.Register(this.GetType().Name,this); } }

  34. Пример№3 ВязыкеJavaстойжецельюиспользуетсястатический блокинициализации: publicclassSingletonextendsRegSingleton { static { newSingleton(); } protectedSingleton() { RegSingleton.Register(this.getClass().getName(),this); } }

  35. Пример№4 ВязыкеC++всереализацииодиночкиявляются вариациямиегоосновнойформы: classSingleton { public: staticSingleton&Instance() { if(!pInstance) pInstance=newSingleton(); return*pInstance; } private: Singleton(){} Singleton(constSingleton&); Singleton&operator=(constSingleton&); ~Singleton(){} staticSingleton*pInstance; };

  36. Пример№4 Всеконструкторыобъектазакрыты,чтоне позволяетпользовательскомукодунапрямую создаватьобъектыклассаSingleton. ДлязащитыотудаленияметодInstance возвращаетссылку,анеуказатель.Также деструкторклассаобъявлензакрытым. Защитуоткопированияобеспечиваетзакрытый конструкторкопирования. Длязащитыотприсваивания(т.к.экземпляр объектаединственныйилюбоеприсваивание являетсясамоприсваиванием),оператор присваиванияобъявлензакрытым.    

  37. Пример№5.СинглтонМейерса Несмотрянато,чтовыделеннаядляобъекта-одиночки памятьбудетосвобожденаоперационнойсистемой, деструкторобъектадолженбытьвызванвоизбежание утечкиресурсов,которыемогзапроситьобъект. Первоерешениепроблемы:СинглтонМейерса,который используетлокальнуюстатическуюпеременную: Singleton&Singleton::Instance() { staticSingletonobj; returnobj; }

  38. Пример№6 СинглтонМейерсаработаетвбольшинствеслучаев,однако нерешаетпроблемывисячейссылки,котораяможет возникнутьвслучаеобращениякобъекту-одиночкепосле егоуничтожения. Первоерешениепроблемывисячейссылкисостоитв созданиифлагаdestroyedигенерацииисключенияпри попыткедоступакуничтоженномуобъекту: classSingleton{ public: staticSingleton&Instance(){ if(!pInstance){ if(destroyed) OnDeadReference(); else Create(); } return*pInstance; } };

  39. Пример№6 classSingleton { staticvoidOnDeadReference() { throwstd::runtime_error("Висячаяссылка"); } staticvoidCreate() { staticSingletonobj; pInstance=&obj; } staticbooldestroyed; staticSingleton*pInstance; };

  40. Пример№6.СинглтонФеникс Второерешениепроблемывисячейссылкисостоитвиспользовании расширенноговариантаоператораnew,которыйпозволяетсоздать объектзановоприобращенииквисячейссылке: classSingleton{ staticvoidOnDeadReference(){ Create(); //ТеперьpInstanceуказываетнаячейкупамяти,где //ранееразмешалсяобъект new(pInstance)Singleton(); //Наместеэтихданныхвновьсоздаётсяобъект atexit(KillPhoenixSingleton); //новыйобъектставитсявочередьнауничтожение destroyed=false; } staticvoidKillPhoenixSingleton(){ pInstance->~Singleton(); //Избегаемосвобожденияпамятиоператоромdelete } };

  41. ФункцияSetLongevity Третьерешениепроблемывисящейссылки:создать объектсявнозаданнымвременемжизни. Времяжизниобъектаможнозадатьприпомощи функцииSetLongevityизбиблиотекиLoki: template<typenameT> voidSetLongevity(T*object,unsignedintlongevity); Даннаяфункциягарантирует,чтообъектobjectбудет уничтоженнеранее,чемобъектысменьшей продолжительностьюжизни.

  42. Пример№7. Заданиевременижизнисинглтона Примерреализациипаттернаодиночкас применениемфункцииSetLongevity: classSingleton { staticvoidCreate() { pInstance=newSingleton(); SetLongevity(pInstance,longevity); } staticconstintlongevity=2; staticSingleton*pInstance; };

  43. Пример№8. Синглтонвмногопоточнойсреде Дляобеспеченияуникальностиобъекта-одиночкив многопоточнойсредеприменяетсяблокировкасдвойной проверкой. РеализацияфункцииInstanceизменяетсяследующим образом: classSingleton{ public: staticSingleton&Instance(){ if(!pInstance){ Lockguard(mutex); if(!pInstance) //Перваяпроверка //Втораяпроверка pInstance=newSingleton(); } return*pInstance; } private: staticMutexmutex; };

  44. Пример№9. Синглтонвмногопоточнойсреде ВязыкеC#блокировкасдвойнойпроверкой реализуетсяприпомощиоператораlock: publicsealedclassSingleton{ privatestaticvolatileSingletoninstance; privatestaticobjectsyncRoot=newObject(); privateSingleton(){} publicstaticSingletonGetInstance() { if(instance==null) //Перваяпроверка { lock(syncRoot) { if(instance==null)//Втораяпроверка instance=newSingleton(); } } returninstance; } }

More Related