Mifano ya ubunifu iliandikwa kwa mara ya kwanza katika kundi maarufu la nne Kitabu kinaonyesha kila mfano katika sura maalum na inafuata muundo mkali kwa kila mmoja: nia, motisha, kutumika, muundo, washiriki, ushirikiano, matokeo, utekelezaji, mifano ya msimbo, matumizi yaliyojulikana, na mifano yanayohusiana. Mipango ya kubuni Kwa mfano, hapa ni kipande cha Mfano wa: Muumba wa Mawazo ya: Kuondoa ujenzi wa kitu ngumu kutoka kwa maonyesho yake ili mchakato huo wa ujenzi unaweza kuunda maonyesho tofauti. Utekelezaji wa: Tumia mtindo wa kujenga wakati the algorithm for creating a complex object should be independent of the Parts that make up the object and how they're assembled. the construction process must allow different representations for the object that's constructed. : Intent Kuondoa ujenzi wa kitu ngumu kutoka kwa maonyesho yake ili mchakato huo wa ujenzi unaweza kuunda maonyesho tofauti. : Applicability Tumia mtindo wa kujenga wakati algorithm kwa ajili ya kujenga kitu ngumu inapaswa kuwa huru ya sehemu ambazo hufanya kitu na jinsi wao ni pamoja. mchakato wa ujenzi unapaswa kuruhusu maonyesho tofauti kwa kitu ambacho kimejengwa. GoF (Gang ya Nne) imekuwa msingi katika uwanja wa Programu ya Object-Oriented na imeathiri kubuni ya lugha za programu, ikiwa ni pamoja na zilizoenea kama vile Java. Kama mimi ni nyuma katika nafasi ya uhandisi, mimi kukutana na coding Java mapya ambayo ina mengi ya uwezo wa kuboresha kuhusiana na kudumisha. Inafanya kazi, lakini mimi kufikiria wahandisi wanahitaji update yake, ikiwa ni pamoja na mwenyewe wa baadaye wa mwandishi wa awali na mimi, na nina uhakika ninaweza kuwasaidia. wiki hii, mimi refactored code kutumia mifano ya ubunifu ili kuboresha kudumisha yake. Muundo wa kujenga na vigezo vingi vya aina hiyo. Hebu fikiria muumba na vigezo vingi vya String: public License ( String id, String licenseeName, String licenseId, String environment, LocalDateTime generatedAt ) Wakati wa kuita mtengenezaji huu, uwezekano ni kwamba mtengenezaji anaweza bila kujali kubadilisha maagizo ya kiwango: var license = new License("My license", "XXX-123", "Customer", "User-acceptance tests", new LocalDateTime()); Oops, nimebadilisha jina la mmiliki wa leseni na ID ya leseni. IDE yako inaweza kusaidia hapa, lakini kuna njia nyingine. Aina ya Wrappers Wapiganaji wa OOP safi watasisitiza kwa furaha kwamba hakuna mtu anapaswa kutumia moja kwa moja string. Badala yake, mtu anapaswa kuingiza kila parameter katika aina maalum, kwa ajili ya Java : ya G. record public record Id(String id) { ... } public record LicenseeName(String licenseeName) { ... } public record LicenseeId(String licenseId) { ... } public record Environment(String environment) { ... } public record GeneratedAt(LocalDateTime generatedAt) { ... } Sasa hatuwezi kufanya makosa: var id = new Id("My license"); var licenseeName = new LicenseeName("Customer"); var licenseId = new LicenseeId("XXX-123"); var environment = new Environment("User-acceptance tests"); var generatedAt = new LocalDateTime(); var license = new License(id, licenseId, licenseName, environment, generatedAt); //1 Makosa ya muda Ingawa mbinu hii bila shaka huongeza uhifadhi, wrapper huongeza ukubwa wa kumbukumbu. ongezeko sahihi linategemea utekelezaji wa JDK, lakini kwa aina moja, ni karibu mara 5 kubwa. Kotlin hufanya upepo kwa kutoa : wrapping ni udhibiti wa muda wa compile, lakini bytecode inaonyesha aina ya wrapped na kiwango chafuatayo: Masomo ya thamani ya inline Jamii inline inapaswa kuwa na mali moja iliyoanzishwa katika muundo wa msingi Jamii inline inapaswa kuwa na mali moja iliyoanzishwa katika muundo wa msingi Maelezo ya Parameter Java inatoa wito wa njia tu na vigezo vya nafasi, lakini lugha zingine, , Python, Kotlin, na Rust, pia hutoa vigezo vya jina. ya G. Hapa ni kujenga Kotlin ambayo inaonyesha darasa la juu: class License ( val id: String, val licenseeName: String, val licenseId: String, val environment: String, val generatedAt: LocalDateTime ) Unaweza kuita mtengenezaji kwa kuita vigezo, hivyo kupunguza hatari ya kufanya makosa: val license = License( id = "My license", licenseeName = "Customer", licenseId = "XXX-123", environment = "User-acceptance tests", generatedAt = LocalDateTime() ) ya Mfano wa Muumba wa ya Mfano ni mbinu nyingine inayowezekana, ingawa sio sehemu ya kesi za matumizi zilizotajwa katika GoF. Muumba wa Hapa ni msimbo wa: public class License { private final String id; private final String licenseeName; private final String licenseId; private final String environment; private final LocalDateTime generatedAt; private License ( //1 String id, String licenseeName, String licenseId, String environment, LocalDateTime generatedAt ) { ... } public static LicenseBuilder builder() { //2 return new LicenseBuilder(); } public static class LicenseBuilder { private String id; //3 private String licenseeName; //3 private String licenseId; //3 private String environment; //3 private LocalDateTime generatedAt; //3 private LicenseBuilder() {} //1 public LicenseBuilder withId(String id) { //4 this.id = id; //5 return this; //4 } // Other `withXXX` methods public License build() { //6 return new License( id, licenseeName, licenseId, environment, generatedAt ); } } } kuzuia ufuatiliaji wa moja kwa moja wa vitu Kuunda Muumba Mpya Majengo ya Muumba hufuata majengo ya kitu Kila mbinu hutoa ubunifu wa kujenga mwenyewe Fikiria juu ya attribute Kurejesha kipengele kamili Sasa mtu anaweza kuita mtengenezaji kama vile: val license = License.builder() .withId("My license") .withLicenseName("Customer") .withLicenseId("XXX-123") .withEnvironment("User-acceptance tests") .withGeneratedAt(new LocalDateTime()) Kuunda msimbo wa kujenga ni maumivu (isipokuwa unatumia AI), lakini inawezesha kusoma bora. Zaidi ya hayo, mtu anaweza kuongeza uthibitisho kwa kila wito wa njia, kuhakikisha kwamba kitu ambacho kinachotengenezwa ni halali. . Muundo wa kujenga Muhtasari wa Approach Pros Cons Type wrappers Object-Oriented Programming - More verbose- Can be memory-heavy depending on the language Named parameters Easy Not available in Java Builder pattern Verbose - Allows creating complex objects- Allows validating aina ya wrapers Programu ya Mkakati wa Object Oriented - zaidi verbose- Inaweza kuwa kumbukumbu ngumu kulingana na lugha Maelezo ya Parameter rahisi ya Haiwezekani kwa Java Muundo wa Pattern Uongo wa - Inakuwezesha kuunda vitu ngumu- Inakuwezesha kuthibitisha Wafanyabiashara wakitumia vikwazo Katika orodha hiyo, nilipata msimbo wafuatao: public Stuff(UuidService uuidService, FallbackUuidService fallbackUuidService) { try { uuid = uuidService.getUuid(); } catch(CannotGetUuidException e) { try { uuid = fallbackUuidService.getUuid(); } catch(CannotGetUuidException e1) { uuid = "UUID can be fetched"; } } } Pamoja na uzoefu mdogo, unaweza kutambua kile kinachotokea katika kipande cha hapo juu. Ikiwa huduma zote mbili zinashindwa, imeanzishwa na mstari ambao sio UUID. Kodi yote ambayo inategemea UUID inapaswa kukabiliana na thamani ambazo zinaweza kuwa sio UUUID. Mtu anapaswa kushindwa haraka. ufumbuzi wa haraka utaonekana kama hii: uuid public Stuff(UuidService uuidService, FallbackUuidService fallbackUuidService) { try { uuid = uuidService.getUuid(); } catch(CannotGetUuidException e) { try { uuid = fallbackUuidService.getUuid(); } catch(CannotGetUuidException e1) { throw new RuntimeException(e1); } } } Sasa, kila mmoja Object ina UUID halali. Hata hivyo, kutupa pengo ndani ya constructors ina matatizo ya uwezekano: Stuff Utoaji wa rasilimali: Ikiwa mtengenezaji hutenga rasilimali (kwa mfano, faili, sockets) na hupoteza kipimo, rasilimali hizi zinaweza kutolewa. Urithi: Ikiwa mtengenezaji wa darasa la juu anatoa kipimo, mtengenezaji wa darasa la chini hautafanya kazi. Matatizo yaliyochaguliwa: Haiwezekani kutumia matatizo yaliyochaguliwa katika waendeshaji, tu wakati wa uendeshaji. Kwa sababu hizi, nadhani ukosefu hauna nafasi yao katika constructors na mimi kuepuka. mfano ulioelezwa katika sehemu ya kwanza, lakini kama ilivyoelezwa, ni mengi ya msimbo; Sidhani kwamba ni muhimu. . Muumba wa Njia ya viwanda kujaribu Kufafanua interface kwa ajili ya kuunda kitu, lakini kuruhusu madarasa ya chini kuamua ambayo darasa ya instantiate. Utekelezaji Tumia mfumo wa mtindo wa kiwanda wakati: darasa haiwezi kutabiri darasa la vitu anapaswa kuunda. Jamii inataka makundi yake ya chini kufafanua vitu ambavyo huunda. masomo kuhamisha wajibu kwa moja ya madarasa kadhaa ya msaidizi, na unataka kuhamisha ujuzi wa ambayo madarasa ya msaidizi ni msaidizi. Intent Kufafanua interface kwa ajili ya kuunda kitu, lakini kuruhusu madarasa ya chini kuamua ambayo darasa ya instantiate. Applicability Tumia mfumo wa mtindo wa kiwanda wakati: darasa haiwezi kutabiri darasa la vitu anapaswa kuunda. Jamii inataka makundi yake ya chini kufafanua vitu ambavyo huunda. masomo kuhamisha wajibu kwa moja ya madarasa kadhaa ya msaidizi, na unataka kuhamisha ujuzi wa ambayo madarasa ya msaidizi ni msaidizi. Kumbuka kwamba katika kesi hii, sisi kutumia kwa sababu nyingine. Hapa ni msimbo updated: public class Stuff { private final UUID uuid; private Stuff(UUID uuid) { //1 this.uuid = uuid; } public static Stuff create(UuidService uuidService, FallbackUuidService fallbackUuidService) throws CannotGetUuidException { try { return new Stuff(uuidService.getUuid()); } catch(CannotGetUuidException e) { return new Stuff(fallbackUuidService.getUuid()); //2 } } } kuzuia uteuzi wa nje Ikiwa haifai, inachukua CannotGetUuidException mpya Mmoja anaitwa juu kama hii: var stuff = Stuff.create(uuidService, fallbackUuidService); //1 Hakuna haja ya kuondokana na upungufu wa Katika hatua hii, sisi ni uhakika kwamba kitu ni kamili initialized kama wito mafanikio. kama haina, hakuna kitu huundwa. Mwisho wa Katika chapisho hili, nimeelezea matumizi mawili ya mifano ya ubunifu ya GoF, ambayo haijaorodheshwa katika kitabu: kuboresha uhifadhi na kuhakikisha vitu vimeanzishwa kikamilifu. To go further: Mipango ya Design ya GoF Kuingia katika mtindo wa Muumba Mfano wa Muumba ni mashine ya hali ya mwisho! Awali ilichapishwa katika A Java Geek juu ya Agosti 31st, 2025 Mfano wa Java Geek