คำถามติดแท็ก builder-pattern

1
“ StringBuilder” เป็นแอปพลิเคชั่นของรูปแบบการออกแบบตัวสร้างหรือไม่?
รูปแบบ "ตัวสร้าง" ถูก จำกัด ให้จัดการกับรูปแบบการต่อต้าน "ตัวสร้างเหลื่อม" หรืออาจกล่าวได้ว่าเป็นการแก้ปัญหาทั่วไปของการสร้างวัตถุที่ไม่เปลี่ยนรูปแบบที่ซับซ้อนมากขึ้นหรือไม่? StringBuilderชั้นจะมีคำว่า "ผู้สร้าง" ในชื่อของมัน แต่มันมีอะไรจะทำอย่างไรกับความเหลื่อมก่อสร้างมันก็ช่วยให้เราได้รวบรวมข้อมูลทั้งหมดที่เราต้องผ่านการสร้างของวัตถุที่ไม่เปลี่ยนรูป สำหรับฉันดูเหมือนว่าคำตอบจะชัดเจนมาก "ใช่" แต่ดูเหมือนจะมีความขัดแย้งในหัวข้อดังนั้นฉันหวังว่าบางคนอาจจะอธิบายได้ ฉันตอบคำถามนี้: โปรแกรมเมอร์ SE: "งานจริง" ที่ถูกต้องในตัวสร้าง? ที่ OP ต้องการสร้างวัตถุ (น่าจะไม่เปลี่ยนรูป) ที่มีต้นไม้ที่ซับซ้อนและความคิดของรูปแบบ "ผู้สร้าง" โผล่ขึ้นมาและในขณะที่ทำการวิจัยผมพบว่า Q&A นี้ซึ่งดูเหมือนว่ารูปแบบการสร้างวัตถุ "StringBuilder" คือไม่ได้เป็นโปรแกรมของ "สร้าง" รูปแบบสำหรับเหตุผลที่ไม่ชัดเจนกับผม: Stackoverflow - StringBuilder และสร้างรูปแบบ (ผู้ที่ตอบคำถามนั้นล้มเหลวในการสร้างจุดที่น่าเชื่อถือเท่าที่ฉันสามารถบอกได้)

9
ทำไมเราต้องมีคลาส Builder เมื่อใช้รูปแบบตัวสร้าง?
ฉันเห็นการใช้งานหลายอย่างของรูปแบบตัวสร้าง (ส่วนใหญ่ใน Java) พวกเขาทั้งหมดมีคลาสเอนทิตี้ (สมมุติว่าPersonคลาส) และคลาสบิลPersonBuilderเดอร์ ผู้สร้าง "สแต็ค" ฟิลด์ที่หลากหลายและส่งกลับค่าnew Personด้วยอาร์กิวเมนต์ที่ส่งผ่าน ทำไมเราต้องมีคลาสผู้สร้างอย่างชัดเจนแทนที่จะใส่เมธอดผู้สร้างทั้งหมดลงในPersonคลาสเอง? ตัวอย่างเช่น: class Person { private String name; private Integer age; public Person() { } Person withName(String name) { this.name = name; return this; } Person withAge(int age) { this.age = age; return this; } } ฉันสามารถพูดได้ Person john = …

8
ฉันจะโปรโมตการใช้รูปแบบเครื่องมือสร้างในทีมของฉันได้อย่างไร
codebase ของเรานั้นเก่าและโปรแกรมเมอร์ใหม่อย่างฉันเรียนรู้ที่จะทำอย่างที่มันทำเพื่อความสม่ำเสมอ เมื่อคิดว่าเราจะต้องเริ่มต้นที่ไหนสักแห่งฉันก็เลยทำมันเองเพื่อสร้างคลาสของตัวยึดข้อมูลอีกครั้ง: ลบเมธอด setter และสร้างฟิลด์ทั้งหมดfinal(ฉันใช้ " finalดี" ตามหลักการ) ตัวตั้งค่าถูกใช้เฉพาะในตัวสร้างเมื่อมันปรากฏออกดังนั้นสิ่งนี้จึงไม่มีผลข้างเคียง แนะนำคลาส Builder คลาส Builder นั้นจำเป็นเนื่องจากตัวสร้าง (ซึ่งเป็นสิ่งที่ให้การรีแฟคเตอร์ใหม่ในตอนแรก) ครอบคลุมโค้ดประมาณ 3 บรรทัด แต่ก็มีจำนวนมากของพารามิเตอร์ โชคดีที่มีมันเพื่อนร่วมทีมของฉันกำลังทำงานในโมดูลอื่นและเกิดขึ้นเพื่อต้องการผู้ตั้งค่าเนื่องจากค่าที่เขาต้องการนั้นมีอยู่ในจุดต่าง ๆ ในการไหล ดังนั้นรหัสดูเหมือนว่านี้: public void foo(Bar bar){ //do stuff bar.setA(stuff); //do more stuff bar.setB(moreStuff); } ฉันเป็นที่ถกเถียงกันอยู่ว่าเขาควรจะใช้ผู้สร้างแทนเพราะการกำจัด setters ทำให้ทุ่งนาไม่สามารถเปลี่ยนแปลงได้ (พวกเขาเคยได้ยินว่าฉันโกรธมากเกี่ยวกับความไม่สามารถเปลี่ยนแปลงได้ก่อนหน้านี้) และเพราะผู้สร้างอนุญาตให้สร้างวัตถุ ฉันร่างรหัสเทียมต่อไปนี้: public void foo(Bar bar){ try{ bar.setA(a); //enter exception-throwing …

3
ตัวสร้างที่มีพารามิเตอร์เป็นจำนวนมากเทียบกับรูปแบบตัวสร้าง
มันเป็นที่รู้จักกันดีว่าถ้าชั้นเรียนของคุณมีคอนสตรัคกับปัจจัยหลายประการพูดมากกว่า 4 แล้วมันเป็นส่วนใหญ่อาจจะเป็นกลิ่นรหัส คุณจำเป็นต้องพิจารณาถ้าตอบสนองระดับSRP แต่ถ้าเราสร้างและวัตถุที่ขึ้นอยู่กับพารามิเตอร์ 10 พารามิเตอร์ขึ้นไปและในที่สุดก็สิ้นสุดด้วยการตั้งค่าพารามิเตอร์ทั้งหมดผ่านรูปแบบตัวสร้าง ลองนึกภาพคุณสร้างPersonวัตถุประเภทที่มีข้อมูลส่วนบุคคลข้อมูลการทำงานข้อมูลเพื่อนข้อมูลความสนใจข้อมูลการศึกษาและอื่น ๆ สิ่งนี้ดีอยู่แล้ว แต่คุณตั้งค่าพารามิเตอร์เดียวกันมากกว่า 4 ตัวใช่ไหม? ทำไมทั้งสองกรณีนี้ไม่ถือว่าเหมือนกัน?

5
ทำไมประเภทจะควบคู่ไปกับการสร้าง?
ฉันเพิ่งลบคำตอบjavaของฉันในการตรวจสอบรหัสที่เริ่มต้นเช่นนี้: private Person(PersonBuilder builder) { หยุด. ธงแดง PersonBuilder จะสร้างบุคคล มันรู้เกี่ยวกับบุคคล คลาส Person ไม่ควรรู้อะไรเกี่ยวกับ PersonBuilder - เป็นเพียงประเภทที่ไม่เปลี่ยนรูป คุณสร้างคัปปลิ้งแบบวงกลมตรงนี้โดยที่ A ขึ้นอยู่กับ B ซึ่งขึ้นอยู่กับ A บุคคลนั้นควร จำกัด พารามิเตอร์ของตน ลูกค้าที่เต็มใจสร้างบุคคลโดยไม่สร้างมันควรจะสามารถทำเช่นนั้นได้ ฉันถูกตบด้วย downvote และบอกว่า (อ้างถึง) การตั้งค่าสถานะสีแดงทำไม? การใช้งานที่นี่มีรูปร่างเดียวกับที่ Joshua Bloch แสดงในหนังสือ "Effective Java" ของเขา (รายการ # 2) ดังนั้นดูเหมือนว่าวิธีที่ถูกต้องในการนำรูปแบบการสร้างมาใช้ใน Java คือการสร้างชนิดซ้อน (นี่ไม่ใช่สิ่งที่คำถามนี้เกี่ยวกับว่า) และจากนั้นสร้างผลิตภัณฑ์ (คลาสของวัตถุที่ถูกสร้างขึ้น ) ใช้การพึ่งพาผู้สร้างเช่นนี้ private …

4
อาร์กิวเมนต์ที่ระบุชื่อแทนที่รูปแบบตัวสร้างหรือไม่
เมื่อใช้ภาษาที่สนับสนุนอาร์กิวเมนต์ที่ตั้งชื่อและเป็นตัวเลือกรูปแบบตัวสร้างจะไม่มีประโยชน์ในทางปฏิบัติอีกต่อไปหรือไม่ ผู้สร้าง: new Builder(requiredA, requiredB).setOptionalA("optional").Build(); อาร์กิวเมนต์ตัวเลือก / ชื่อ: new Object(requiredA, requiredB, optionalA: "optional");

4
Java: วิธีการใช้เครื่องมือสร้างขั้นตอนซึ่งลำดับของ setters ไม่สำคัญ?
แก้ไข:ฉันต้องการจะชี้ให้เห็นว่าคำถามนี้อธิบายถึงปัญหาทางทฤษฎีและฉันรู้ว่าฉันสามารถใช้อาร์กิวเมนต์ตัวสร้างสำหรับพารามิเตอร์บังคับหรือส่งข้อยกเว้น runtime ถ้าใช้ API ไม่ถูกต้อง อย่างไรก็ตามฉันกำลังมองหาวิธีแก้ปัญหาที่ไม่ต้องการตัวสร้างอาร์กิวเมนต์หรือการตรวจสอบรันไทม์ ลองนึกภาพคุณมีCarอินเทอร์เฟซเช่นนี้: public interface Car { public Engine getEngine(); // required public Transmission getTransmission(); // required public Stereo getStereo(); // optional } ตามความคิดเห็นที่จะแนะนำCarต้องมีEngineและTransmissionแต่Stereoเป็นตัวเลือก นั่นหมายความว่าสร้างที่สามารถเพียงตัวอย่างที่เคยควรจะมีวิธีการถ้าและมีทั้งรับแล้วมอบให้กับผู้สร้างอินสแตนซ์ ด้วยวิธีการตรวจสอบชนิดจะปฏิเสธที่จะรวบรวมรหัสใด ๆ ที่พยายามที่จะสร้างอินสแตนซ์โดยไม่ต้องหรือbuild()Carbuild()EngineTransmissionCarEngineTransmission สายนี้สำหรับสร้างขั้นตอน โดยทั่วไปแล้วคุณจะใช้สิ่งนี้: public interface Car { public Engine getEngine(); // required public Transmission getTransmission(); // required public Stereo …

3
มีจุดใดบ้างในการใช้ตัวสร้างและส่วนต่อประสานกับวัตถุเริ่มต้น?
ใน Java และ C # คุณสามารถสร้างวัตถุที่มีคุณสมบัติที่สามารถตั้งค่าได้ที่การเริ่มต้นโดยการกำหนดตัวสร้างด้วยพารามิเตอร์การกำหนดแต่ละคุณสมบัติหลังจากการสร้างวัตถุหรือการใช้รูปแบบส่วนต่อประสานการสร้าง / ของเหลว อย่างไรก็ตาม C # 3 แนะนำวัตถุเริ่มต้นและคอลเลกชันซึ่งหมายความว่ารูปแบบการสร้างไม่ได้ผลส่วนใหญ่ ในภาษาที่ไม่มีค่าเริ่มต้นเราสามารถใช้เครื่องมือสร้างจากนั้นใช้มันเพื่อ: Vehicle v = new Vehicle.Builder() .manufacturer("Toyota") .model("Camry") .year(1997) .colour(CarColours.Red) .addSpecialFeature(new Feature.CDPlayer()) .addSpecialFeature(new Feature.SeatWarmer(4)) .build(); ในทางกลับกันใน C # one สามารถเขียน: var vehicle = new Vehicle { Manufacturer = "Toyota", Model = "Camry", Year = 1997, Colour = …
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.