Будівельник (англ. Builder) — шаблон проєктування, належить до класу твірних шаблонів. На відміну від шаблону абстрактної фабрики і фабричного методу, ціль яких є застосування поліморфізму, задачею шаблону будівельника є забезпечення реалізації антишаблону телескопічного (багатоступеневого) конструювання. Антишаблон «телескопічний конструктор» коли різна комбінація параметрів конструктора призводить до появи експоненційної множини конструкторів. Замість того, щоб використовувати набір конструкторів, використовують шаблон будівельник, згідно з яким використовують інший об'єкт (будівельник), що отримує на вхід вхідні параметри по одному, крок за кроком, і повертає за один прохід результуючий створений об'єкт.
Призначення
Відокремлює конструювання складного об'єкта від його подання, таким чином у результаті одного й того ж процесу конструювання можуть бути отримані різні подання.
Мотивація
Вам запропоновано створити систему планування екскурсій по Паттернленду — новому парку розваг. Гості парку можуть вибрати готель, замовити квитки на атракціони, зарезервувати місця в ресторані і навіть замовити спеціальні заходи. Поїздки можуть відрізнятися за кількістю днів і складу розважальної програми. Наприклад, місцевий житель не бажає зупинятися у готелі, але хоче замовити обід та спеціальні заходи. Другий гість прилітає літаком і йому необхідно забронювати номер в готелі, столик в ресторані і квитки на заходи. Таким чином, нам потрібна гнучка структура даних, яка може представляти програму поселення з усіма можливими варіаціями; крім того, побудова програми може складатися з декількох кроків.
Застосування
Слід використовувати шаблон Будівельник коли:
- алгоритм створення складного об'єкта не повинен залежати від того, з яких частин складається об'єкт та як вони стикуються поміж собою;
- процес конструювання повинен забезпечити різні подання об'єкта, що конструюється.
Структура
- Builder — будівельник:
- визначає абстрактний інтерфейс для створення частин об'єкта Product;
- ConcreteBuilder — конкретний будівельник:
- конструює та збирає докупи частини продукту шляхом реалізації інтерфейсу Builder;
- визначає подання, що створюється, та слідкує на ним;
- надає інтерфейс для доступу до продукту;
- Director — керівник:
- конструює об'єкт, користуючись інтерфейсом Builder;
- Product — продукт:
- подає складний конструйований об'єкт. ConcreteBuilder будує внутрішнє подання продукту та визначає процес його складання;
- вносить класи, що визначають складені частини, у тому числі інтерфейси для складання кінцевого результату з частин.
Переваги
- дозволяє змінювати внутрішнє представлення продукту;
- ізолює код, який реалізує конструювання та подання;
- дає тонший контроль над процесом конструювання.
Недоліки
- Потрібно створити окремий ConcreteBuilder для кожного окремого продукту.
Відносини
- клієнт створює об'єкт-управитель Director та конфігурує його потрібним об'єктом-будівником Builder;
- управитель повідомляє будівельника про те, що потрібно побудувати наступну частину продукту;
- будівельник оброблює запити управителя та додає нові частини до продукту;
- клієнт забирає продукт у будівельника.
Реалізація
Приклад С++
#include <iostream> #include <string> using namespace std; // Builder class CReportBuilder { public: virtual ~CReportBuilder() {}; virtual void CreateHeader() = 0; virtual void CreateBody() = 0; virtual void CreateFooter() = 0; virtual void Print() { cout << m_strReport << endl; }; protected: string m_strReport; }; // Конкретний будівельник 1 struct CTextReportBuilder : public CReportBuilder { virtual ~CTextReportBuilder() {}; virtual void CreateHeader() { m_strReport.append("SIMPLE REPORT'S HEADER \n"); }; virtual void CreateBody() { m_strReport.append("\n\"Simple Report's Main Text\"\n \n"); }; virtual void CreateFooter() { m_strReport.append("Simple Report's Footer \n"); }; }; // Конкретний будівельник 2 struct CHTMLReportBuilder : public CReportBuilder { virtual ~CHTMLReportBuilder() {}; virtual void CreateHeader() { m_strReport.append("<HTML><BODY> \n"); m_strReport.append("<H1>HTML REPORT'S HEADER</H1> \n"); }; virtual void CreateBody() { m_strReport.append("<p>\"HTML Report's Main Text\"</p> \n"); }; virtual void CreateFooter() { m_strReport.append("<p><i>HTML Report's Footer</i></p> \n"); m_strReport.append("</BODY></HTML>"); }; }; // Director. Створює продукт використовуючи інтерфейс Будівельника void CreateReport(CReportBuilder& report) { report.CreateHeader(); report.CreateBody(); report.CreateFooter(); }; void main() { CHTMLReportBuilder Report; // Product CreateReport(Report); Report.Print(); }
Приклад Swift
class DeathStarBuilder { var x: Double? var y: Double? var z: Double? typealias BuilderClosure = (DeathStarBuilder) -> () init(buildClosure: BuilderClosure) { buildClosure(self) } } struct DeathStar : CustomStringConvertible { let x: Double let y: Double let z: Double init?(builder: DeathStarBuilder) { if let x = builder.x, y = builder.y, z = builder.z { self.x = x self.y = y self.z = z } else { return nil } } var description:String { return "Death Star at (x:\(x) y:\(y) z:\(z))" } } let empire = DeathStarBuilder { builder in builder.x = 0.1 builder.y = 0.2 builder.z = 0.3 } let deathStar = DeathStar(builder:empire)
Джерела
- Design Patterns: Elements of Reusable Object-Oriented Software [ 9 листопада 2012 у Wayback Machine.]
- Design Patterns implemented in Swift 2 [ 30 січня 2016 у Wayback Machine.]
Література
Алан Шаллоуей, Джеймс Р. Тротт. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М. : «Вильямс», 2002. — 288 с. — .
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Budivelnik angl Builder shablon proyektuvannya nalezhit do klasu tvirnih shabloniv Na vidminu vid shablonu abstraktnoyi fabriki i fabrichnogo metodu cil yakih ye zastosuvannya polimorfizmu zadacheyu shablonu budivelnika ye zabezpechennya realizaciyi antishablonu teleskopichnogo bagatostupenevogo konstruyuvannya Antishablon teleskopichnij konstruktor koli rizna kombinaciya parametriv konstruktora prizvodit do poyavi eksponencijnoyi mnozhini konstruktoriv Zamist togo shob vikoristovuvati nabir konstruktoriv vikoristovuyut shablon budivelnik zgidno z yakim vikoristovuyut inshij ob yekt budivelnik sho otrimuye na vhid vhidni parametri po odnomu krok za krokom i povertaye za odin prohid rezultuyuchij stvorenij ob yekt PriznachennyaVidokremlyuye konstruyuvannya skladnogo ob yekta vid jogo podannya takim chinom u rezultati odnogo j togo zh procesu konstruyuvannya mozhut buti otrimani rizni podannya MotivaciyaVam zaproponovano stvoriti sistemu planuvannya ekskursij po Patternlendu novomu parku rozvag Gosti parku mozhut vibrati gotel zamoviti kvitki na atrakcioni zarezervuvati miscya v restorani i navit zamoviti specialni zahodi Poyizdki mozhut vidriznyatisya za kilkistyu dniv i skladu rozvazhalnoyi programi Napriklad miscevij zhitel ne bazhaye zupinyatisya u goteli ale hoche zamoviti obid ta specialni zahodi Drugij gist prilitaye litakom i jomu neobhidno zabronyuvati nomer v goteli stolik v restorani i kvitki na zahodi Takim chinom nam potribna gnuchka struktura danih yaka mozhe predstavlyati programu poselennya z usima mozhlivimi variaciyami krim togo pobudova programi mozhe skladatisya z dekilkoh krokiv ZastosuvannyaSlid vikoristovuvati shablon Budivelnik koli algoritm stvorennya skladnogo ob yekta ne povinen zalezhati vid togo z yakih chastin skladayetsya ob yekt ta yak voni stikuyutsya pomizh soboyu proces konstruyuvannya povinen zabezpechiti rizni podannya ob yekta sho konstruyuyetsya StrukturaUML diagrama klasiv sho opisuye strukturu shablonu proyektuvannya BudivnikBuilder budivelnik viznachaye abstraktnij interfejs dlya stvorennya chastin ob yekta Product ConcreteBuilder konkretnij budivelnik konstruyuye ta zbiraye dokupi chastini produktu shlyahom realizaciyi interfejsu Builder viznachaye podannya sho stvoryuyetsya ta slidkuye na nim nadaye interfejs dlya dostupu do produktu Director kerivnik konstruyuye ob yekt koristuyuchis interfejsom Builder Product produkt podaye skladnij konstrujovanij ob yekt ConcreteBuilder buduye vnutrishnye podannya produktu ta viznachaye proces jogo skladannya vnosit klasi sho viznachayut skladeni chastini u tomu chisli interfejsi dlya skladannya kincevogo rezultatu z chastin Perevagidozvolyaye zminyuvati vnutrishnye predstavlennya produktu izolyuye kod yakij realizuye konstruyuvannya ta podannya daye tonshij kontrol nad procesom konstruyuvannya NedolikiPotribno stvoriti okremij ConcreteBuilder dlya kozhnogo okremogo produktu Vidnosinikliyent stvoryuye ob yekt upravitel Director ta konfiguruye jogo potribnim ob yektom budivnikom Builder upravitel povidomlyaye budivelnika pro te sho potribno pobuduvati nastupnu chastinu produktu budivelnik obroblyuye zapiti upravitelya ta dodaye novi chastini do produktu kliyent zabiraye produkt u budivelnika UML diagrama poslidovnosti sho opisuye vzayemovidnosini mizh budivnikom ta kliyentomRealizaciyaPriklad S Priklad realizaciyi movoyu S include lt iostream gt include lt string gt using namespace std Builder class CReportBuilder public virtual CReportBuilder virtual void CreateHeader 0 virtual void CreateBody 0 virtual void CreateFooter 0 virtual void Print cout lt lt m strReport lt lt endl protected string m strReport Konkretnij budivelnik 1 struct CTextReportBuilder public CReportBuilder virtual CTextReportBuilder virtual void CreateHeader m strReport append SIMPLE REPORT S HEADER n virtual void CreateBody m strReport append n Simple Report s Main Text n n virtual void CreateFooter m strReport append Simple Report s Footer n Konkretnij budivelnik 2 struct CHTMLReportBuilder public CReportBuilder virtual CHTMLReportBuilder virtual void CreateHeader m strReport append lt HTML gt lt BODY gt n m strReport append lt H1 gt HTML REPORT S HEADER lt H1 gt n virtual void CreateBody m strReport append lt p gt HTML Report s Main Text lt p gt n virtual void CreateFooter m strReport append lt p gt lt i gt HTML Report s Footer lt i gt lt p gt n m strReport append lt BODY gt lt HTML gt Director Stvoryuye produkt vikoristovuyuchi interfejs Budivelnika void CreateReport CReportBuilder amp report report CreateHeader report CreateBody report CreateFooter void main CHTMLReportBuilder Report Product CreateReport Report Report Print Priklad Swift Priklad realizaciyi movoyu Swift class DeathStarBuilder var x Double var y Double var z Double typealias BuilderClosure DeathStarBuilder gt init buildClosure BuilderClosure buildClosure self struct DeathStar CustomStringConvertible let x Double let y Double let z Double init builder DeathStarBuilder if let x builder x y builder y z builder z self x x self y y self z z else return nil var description String return Death Star at x x y y z z let empire DeathStarBuilder builder in builder x 0 1 builder y 0 2 builder z 0 3 let deathStar DeathStar builder empire DzherelaDesign Patterns Elements of Reusable Object Oriented Software 9 listopada 2012 u Wayback Machine Design Patterns implemented in Swift 2 30 sichnya 2016 u Wayback Machine LiteraturaAlan Shallouej Dzhejms R Trott Shablony proektirovaniya Novyj podhod k obektno orientirovannomu analizu i proektirovaniyu Design Patterns Explained A New Perspective on Object Oriented Design M Vilyams 2002 288 s ISBN 0 201 71594 5