โหมดผู้สร้าง
คำจำกัดความเรียกอีกอย่างว่ารูปแบบเครื่องกำเนิดไฟฟ้า มันสามารถสรุปกระบวนการก่อสร้างของวัตถุที่ซับซ้อน (หมวดหมู่นามธรรม) ดังนั้นวิธีการใช้งานที่แตกต่างกันของกระบวนการนามธรรมนี้สามารถสร้างวัตถุที่มีอาการที่แตกต่างกัน (แอตทริบิวต์)
เมื่ออัลกอริทึมสำหรับการสร้างวัตถุที่ซับซ้อนควรเป็นอิสระจากส่วนประกอบของวัตถุนั้นและกระบวนการก่อสร้างจะต้องอนุญาตให้วัตถุที่สร้างขึ้นมีการเป็นตัวแทนที่แตกต่างกัน เราอาจพิจารณาใช้โหมด Builder
ทำให้สำเร็จ
1. Builder ระบุอินเทอร์เฟซนามธรรมสำหรับแต่ละองค์ประกอบที่สร้างวัตถุผลิตภัณฑ์ โดยปกติแล้วจะมีวิธีการนามธรรมที่สร้างและส่งคืนผลิตภัณฑ์หรืออาจเป็นวิธีคอนกรีตวางกระบวนการสร้างลงในคลาสคอนกรีต
2. ConcreteBuilder ใช้อินเทอร์เฟซตัวสร้างเพื่อสร้างและรวบรวมส่วนประกอบต่าง ๆ ของผลิตภัณฑ์
3. ผู้อำนวยการรับผิดชอบในการโทรหาผู้สร้างที่เหมาะสมเพื่อสร้างผลิตภัณฑ์ โดยทั่วไปคลาสผู้อำนวยการไม่ได้ขึ้นอยู่กับคลาสผลิตภัณฑ์ คลาส Builder โต้ตอบโดยตรงกับชั้นเรียนผู้กำกับ
4. ผลิตภัณฑ์แสดงถึงวัตถุที่ซับซ้อนที่จะสร้าง ConcreateBuilder สร้างการเป็นตัวแทนภายในของผลิตภัณฑ์และกำหนดกระบวนการประกอบ
/ ** "ผลิตภัณฑ์"*/ คลาสพิซซ่า {private String dough = ""; ซอสสตริงส่วนตัว = ""; สตริงส่วนตัว topping = ""; โมฆะสาธารณะ setdough (แป้งสตริง) {this.dough = แป้ง; } โมฆะสาธารณะ setSauce (ซอสสตริง) {this.sauce = ซอส; } โมฆะสาธารณะ settopping (topping สตริง) {this.topping = topping; }} ''/** "Abstract Builder"*/'' Abstract Class Pizzabuilder {พิซซ่าพิซซ่าป้องกัน; พิซซ่าสาธารณะ getPizza () {กลับพิซซ่า; } โมฆะสาธารณะ createNewPizzAproduct () {พิซซ่า = ใหม่พิซซ่า (); } โมฆะนามธรรมสาธารณะ Builddough (); โมฆะนามธรรมสาธารณะ Buildsauce (); บทคัดย่อสาธารณะเป็นโมฆะสาธารณะ buildtopping (); } / ** "ConcreteBuilder"* / คลาส Hawaiianpizzabuilder ขยาย Pizzabuilder {โมฆะสาธารณะ builddough () {pizza.setdough ("Cross"); } โมฆะสาธารณะ buildsauce () {pizza.setsauce ("อ่อน"); } โมฆะสาธารณะ buildTopping () {pizza.settopping ("แฮม+สับปะรด"); }} / ** "ConcreteBuilder"* / คลาส spicypizzabuilder ขยาย pizzabuilder {โมฆะสาธารณะ builddough () {pizza.setdough ("Pan Baked"); } โมฆะสาธารณะ buildsauce () {pizza.setsauce ("ร้อน"); } โมฆะสาธารณะ buildTopping () {pizza.settopping ("Pepperoni+Salami"); }} ''/** "ผู้กำกับ"*/'' บริกร {Pizzabuilder ส่วนตัว Pizzabuilder; โมฆะสาธารณะ setpizzabuilder (pizzabuilder pb) {pizzabuilder = pb; } พิซซ่าสาธารณะ getPizza () {return pizzabuilder.getPizza (); } โมฆะสาธารณะ constructPizza () {pizzabuilder.createnewpizzaproduct (); Pizzabuilder.builddough (); Pizzabuilder.buildsauce (); Pizzabuilder.buildtopping (); }} /** ลูกค้าสั่งพิซซ่า */ คลาส builderExample {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {พนักงานเสิร์ฟบริกร = บริกรใหม่ (); pizzabuilder hawaiian_pizzabuilder = ใหม่ Hawaiianpizzabuilder (); Pizzabuilder Spicy_Pizzabuilder = ใหม่ spicypizzabuilder (); บริกร บริกร. constructpizza (); พิซซ่าพิซซ่า = บริกร. getPizza (); -ไคลเอนต์สร้างวัตถุผู้กำกับและกำหนดค่าด้วยวัตถุสร้างที่ต้องการ ผู้อำนวยการได้รับคำขอของลูกค้าในการสร้างผลิตภัณฑ์และในที่สุดก็ได้รับผลิตภัณฑ์
ข้อได้เปรียบ
1. กระบวนการสร้างวัตถุสามารถควบคุมได้อย่างรอบคอบเพื่อสร้างวัตถุผลิตภัณฑ์ที่แตกต่างกัน
2. ง่ายต่อการขยาย เมื่อมีผลิตภัณฑ์ใหม่คุณสามารถเพิ่มคอนกรีตบูลเดอร์ใหม่เพื่อให้ได้มัน
รูปแบบรูปแบบที่เกี่ยวข้องรูปแบบโรงงานนามธรรมนั้นคล้ายกับเครื่องกำเนิดไฟฟ้าเพราะยังสามารถสร้างวัตถุที่ซับซ้อนได้ ความแตกต่างที่สำคัญคือรูปแบบเครื่องกำเนิดไฟฟ้ามุ่งเน้นไปที่การสร้างวัตถุที่ซับซ้อนทีละขั้นตอน แบบจำลองโรงงานนามธรรมมุ่งเน้นไปที่วัตถุหลายชุดของวัตถุผลิตภัณฑ์ (ง่ายหรือซับซ้อน)
เครื่องกำเนิดไฟฟ้าส่งคืนผลิตภัณฑ์ในขั้นตอนสุดท้ายและสำหรับโรงงานนามธรรมผลิตภัณฑ์จะกลับมาทันที
โหมดต้นแบบ
การกำหนดรูปแบบต้นแบบเป็นประเภทของรูปแบบการสร้างซึ่งมีลักษณะ "การคัดลอก" อินสแตนซ์ที่มีอยู่เพื่อส่งคืนอินสแตนซ์ใหม่แทนที่จะสร้างอินสแตนซ์ใหม่ ตัวอย่างที่คัดลอกคือสิ่งที่เราเรียกว่า "ต้นแบบ" ซึ่งปรับแต่งได้
โหมดต้นแบบส่วนใหญ่ใช้เพื่อสร้างอินสแตนซ์ที่ซับซ้อนหรือใช้เวลานานเพราะในกรณีนี้การคัดลอกอินสแตนซ์ที่มีอยู่ทำให้โปรแกรมทำงานได้อย่างมีประสิทธิภาพมากขึ้น หรือสร้างค่าที่เท่ากันเพียงแค่ตั้งชื่อข้อมูลที่คล้ายกันที่แตกต่างกัน
ทำให้สำเร็จ
1. ไคลเอนต์ - สร้างวัตถุใหม่จากนั้นรับวัตถุอื่นผ่านโคลน
2. ต้นแบบ - กำหนดวิธีนามธรรมของโคลน
3. Concreteprototype - ใช้วิธีการโคลน
ต้นแบบอินเทอร์เฟซสาธารณะ {วัตถุนามธรรมสาธารณะโคลน (); } คลาสสาธารณะ concreteprototype ใช้ต้นแบบ {object clone () {return super.clone (); }} ไคลเอนต์คลาสสาธารณะ {โมฆะสาธารณะคงที่หลัก (สตริง arg []) {concreteprototype obj1 = ใหม่ concreteprotype (); concreteprototype obj2 = concreteprototype) obj1.clone (); - ตัวอย่าง
1. องค์ประกอบหลายอย่างในเกมซ้ำแล้วซ้ำอีกและเราสามารถใช้โหมดต้นแบบเพื่อคัดลอกองค์ประกอบเดียวกัน
2. เมื่อทำแผนภูมิข้อมูลครั้งแรกที่เราต้องอ่านข้อมูลจากฐานข้อมูลและบันทึกลงในวัตถุ เมื่อเราต้องการสร้างแผนภูมิอื่น ๆ ของข้อมูลเดียวกันการใช้โหมดต้นแบบสามารถหลีกเลี่ยงการอ่านฐานข้อมูลอีกครั้ง
คำถามและการใช้งานที่เกี่ยวข้อง
1. หากจำนวนต้นแบบที่จะสร้างไม่ได้รับการแก้ไขคุณสามารถสร้างตัวจัดการต้นแบบได้ ก่อนที่จะคัดลอกวัตถุต้นแบบไคลเอ็นต์ก่อนตรวจสอบว่ามีวัตถุต้นแบบที่ตรงตามเงื่อนไขในตัวจัดการต้นแบบหรือไม่ หากมีมันจะใช้โดยตรง ถ้าไม่โคลน สิ่งนี้เรียกว่ารูปแบบการลงทะเบียนของโหมดต้นแบบ
2. การคัดลอกสองประเภท: สำเนาลึกและสำเนาตื้น เมื่อคัดลอกวัตถุคัดลอกและวัตถุต้นแบบจะแบ่งปันตัวแปรภายในทั้งหมดของวัตถุและวัตถุทั้งสองมีพื้นที่หน่วยความจำและวงจรชีวิตเดียวกัน การปรับเปลี่ยนของวัตถุต้นแบบยังปรับเปลี่ยนแบบจำลองและในทางกลับกัน
ใน Java ตราบใดที่คุณใช้อินเทอร์เฟซ cloneable คุณสามารถเรียกวิธีการโคลนของคลาสวัตถุเพื่อให้บรรลุการคัดลอกตื้น:
ชั้นเรียนสาธารณะตื้นเขินใช้ cloneable {อายุ int; บุคคล; การตั้งค่าโมฆะสาธารณะ (อายุ int) {this.age = อายุ; } โมฆะสาธารณะ setperson (ชื่อสตริง) {person = บุคคลใหม่ (ชื่อ); } object clone () พ่น clonenotsupportedexception {// java เริ่มต้นใช้งานการคัดลอกตื้นส่งคืน super.clone (); }} บุคคลชั้นเรียนสาธารณะ {ชื่อสตริง; บุคคลสาธารณะ (ชื่อสตริง) {this.name = name; }} การทดสอบระดับสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) พ่น clonenotsupportedexception {ตื้น OldShallowClone = new ตื้น clone (); OldShallowClone.Setage (20); OldShallowClone.SetPerson ("Eric"); System.out.println ("OldName:" + OldShallowClone.person.name + "อายุ:" + oldshallowclone.age); ตื้น NEWShallowClone = (ตื้น clone) oldShallowClone.clone (); System.out.println ("newname:" + newshallowclone.person.name + "อายุ:" + newshallowclone.age); OldShallowClone.age = 30; OldShallowClone.person.name = "Frank"; System.out.println ("newname:" + newshallowclone.person.name + "อายุ:" + newshallowclone.age); - เอาท์พุท:
OldName: Eric Age: 20NewName: Eric อายุ: 20NewName: Frank Age: 20
จะเห็นได้ว่าการคัดลอกวัตถุเป็นการอ้างอิงถึงวัตถุ เมื่อค่าของวัตถุเปลี่ยนไปวัตถุที่คัดลอกจะเปลี่ยนไปและประเภทพื้นฐานของ Java คือค่าที่คัดลอกมา
ด้านล่างเราใช้สำเนาลึก:
ชั้นเรียนสาธารณะ DeepClone {อายุ int; บุคคล; การตั้งค่าโมฆะสาธารณะ (อายุ int) {this.age = อายุ; } โมฆะสาธารณะ setperson (ชื่อสตริง) {person = บุคคลใหม่ (ชื่อ); } สาธารณะ DeepClone (DeepClone DeepClone) {this.age = deepClone.age; this.person = บุคคลใหม่ (deepclone.person.name); } สาธารณะ deepClone () {} object clone () พ่น clonenotsupportedException {ส่งคืน deepClone ใหม่ (นี่); }} การทดสอบระดับสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) พ่น clonenotsupportedException {deepClone oldDeepClone = new DeepClone (); olddeepclone.setage (20); OldDeepClone.SetPerson ("Eric"); System.out.println ("OldName:" + OldDeepClone.person.name + "อายุ:" + olddeepclone.age); deepClone newDeepClone = (deepClone) oldDeepClone.clone (); System.out.println ("newname:" + newdeepclone.person.name + "อายุ:" + newdeepclone.age); olddeepClone.age = 30; OldDeepClone.person.name = "Frank"; System.out.println ("newname:" + newdeepclone.person.name + "อายุ:" + newdeepclone.age); - เอาท์พุท:
OldName: Eric Age: 20NewName: Eric อายุ: 20NewName: Eric Age: 20
ในวิธีการคัดลอกข้างต้นเราสร้างวัตถุขึ้นใหม่และสร้างการอ้างอิงเพื่อใช้สำเนาลึก
ข้อได้เปรียบ
1. การคัดลอกดีกว่าใหม่
2. ทำให้ง่ายขึ้นหรือซ่อนรายละเอียดของการสร้างวัตถุและคัดลอกโดยตรง