อาร์กิวเมนต์ที่ระบุชื่อแทนที่รูปแบบตัวสร้างหรือไม่


20

เมื่อใช้ภาษาที่สนับสนุนอาร์กิวเมนต์ที่ตั้งชื่อและเป็นตัวเลือกรูปแบบตัวสร้างจะไม่มีประโยชน์ในทางปฏิบัติอีกต่อไปหรือไม่

ผู้สร้าง:

new Builder(requiredA, requiredB).setOptionalA("optional").Build();

อาร์กิวเมนต์ตัวเลือก / ชื่อ:

new Object(requiredA, requiredB, optionalA: "optional");

3
คุณจะจัดการกับอาร์กิวเมนต์ที่เป็นตัวเลือก 20 ข้อได้อย่างไร ไม่มีปัญหาที่ Builder ต้องแก้ไขจนกว่าจะมีขนาดใหญ่ ณ จุดที่คุณได้อธิบายไว้ที่นี่คุณมีตัวสร้างสองตัว (และฉันจะไม่สร้างตัวสร้างสำหรับปัญหาเล็ก ๆ )

1
แม้จะมีอาร์กิวเมนต์ที่เป็นตัวเลือก - หากตัวสร้างมีมากกว่า 2 ข้อโต้แย้งฉันชอบใช้วัตถุค่าเพื่อสรุปการกำหนดค่า เช่นเดียวกันสำหรับ fluid inerfaces และ builder: สิ่งที่มากกว่า 3 จะถูกแทนที่ด้วยวัตถุค่า
โทมัสขยะ

คำตอบ:


21

ผู้สร้างมีประโยชน์มากที่สุดเมื่อวัตถุของคุณต้องการอาร์กิวเมนต์ / การพึ่งพาจำนวนมากเพื่อเป็นประโยชน์หรือคุณต้องการอนุญาตวิธีการสร้างวัตถุที่หลากหลาย

จากด้านบนของหัวของฉันฉันสามารถนึกภาพใครบางคนอาจต้องการ "สร้าง" วัตถุในเกม 3 มิติเช่นนี้:

// Just ignore the fact that this hypothetical god class is coupled to everything ever
new ObjectBuilder(x, y, z).importBlenderMesh("./meshes/foo")
                          .syncWithOtherPlayers(serverIP)
                          .compileShaders("./shaders/foo.vert", "./shaders/foo.frag")
                          .makeDestructibleRigidBody(health, weight)
                          ...

ฉันจะโต้แย้งตัวอย่างนี้สามารถอ่านได้มากขึ้นด้วยวิธีการสร้างที่ฉันทำขึ้นตอนนี้มากกว่าที่มันจะมีพารามิเตอร์ทางเลือก:

new Object(x, y, z, meshType: MESH.BLENDER,
                    meshPath: "./meshes/foo",
                    serverToSyncWith: serverIP,
                    vertexShader: "./shaders/foo.vert",
                    physicsType: PHYSICS_ENGINE.RIGID_DESTRUCTIBLE,
                    health: health,
                    weight: weight)
                    ...

โดยเฉพาะอย่างยิ่งข้อมูลที่บอกเป็นนัยโดยชื่อเมธอดตัวสร้างจะต้องถูกแทนที่ด้วยพารามิเตอร์ที่มากกว่าและมันง่ายกว่ามากที่จะลืมเกี่ยวกับหนึ่งพารามิเตอร์ในกลุ่มของพารามิเตอร์ที่เกี่ยวข้องอย่างใกล้ชิด อันที่จริงชิ้นส่วนขาดหายไป แต่คุณจะไม่สังเกตว่าถ้าคุณไม่รู้จักที่จะมองมัน


แน่นอนถ้าวัตถุของคุณใช้เวลาเพียงหนึ่งถึงห้าข้อโต้แย้งในการสร้างไม่จำเป็นต้องมีรูปแบบตัวสร้างที่เกี่ยวข้องไม่ว่าคุณจะตั้งชื่อ / พารามิเตอร์ทางเลือกหรือไม่ก็ตาม


ฉันไม่ซื้อข้อโต้แย้งของคุณ หากชื่อเมธอดตัวสร้างยอดเยี่ยมมากคุณสามารถใช้ชื่อเหล่านี้ได้เช่นกันสำหรับชื่อพารามิเตอร์ หากพารามิเตอร์เกี่ยวข้องอย่างใกล้ชิดให้ใส่ลงในตัวสร้างวัตถุขนาดเล็ก
user949300

@ user949300 ฉันคิดว่าคุณพลาดจุดสำคัญซึ่งเป็นวิธีการสร้างที่นี่อธิบายความสัมพันธ์ระหว่างพารามิเตอร์ที่หายไปหากคุณเพิ่งมีพารามิเตอร์ตัวเลือกมากมาย ในตัวอย่างของ Ixrec ผู้สร้าง "สุขภาพ" และ "น้ำหนัก" เป็นส่วนหนึ่งของการตั้งค่าที่สามารถทำลายได้อย่างมีเหตุผล แต่ความสัมพันธ์นั้นหายไปในเวอร์ชันอาร์กิวเมนต์ที่เป็นทางเลือก
Jules

1
ไม่ใช่ถ้าพารามิเตอร์ตัวเลือกอย่างใดอย่างหนึ่งคือ (ร่างกาย: ใหม่ DestructibleRigidBody (สุขภาพ, น้ำหนัก), ... )
Weyland Yutani

@Jules สิ่งที่ Weyland พูด - สร้างนวกรรมิกชื่อน้ำหนักและส่วนสูง
949300

8

นอกเหนือจากสิ่งที่ Ixrec พูดแล้วตัวสร้างหรือวิธีการตั้งชื่อพารามิเตอร์จะไม่อนุญาตให้คุณมีวัตถุของคุณในสถานะที่จะสร้างซึ่งมันยังคงสามารถแก้ไขได้ก่อนสร้าง นี่คือความงามของผู้สร้างซึ่งคุณสามารถมอบหมายส่วนต่าง ๆ ของการก่อสร้างให้กับวิธีการหรือชั้นเรียนที่แตกต่างกัน:

var myThingBuilder = new ThingBuilder("table");
myThingBuilder.setAttribute(Attributes.Legs, 4);

inventoryManager.setPrices(myThingBuilder);

// inventory manager
var availableCheapestMaterial = getMaterial();
myThingBuilder.setMaterial(availableCheapestMaterial);

โดยพื้นฐานแล้วคุณสามารถที่จะโยนผู้สร้างของคุณไปรอบ ๆ ระบบของคุณจนกว่ามันจะพร้อมที่จะสร้างวัตถุขั้นสุดท้ายช่วยให้คุณสามารถลดจำนวนของความรู้ที่ผู้บริโภคผู้สร้างของคุณต้องการ


ฉันไม่เข้าใจย่อหน้าสุดท้ายของคุณ หากคุณ "โยนผู้สร้างของคุณไปรอบ ๆ ระบบจนกว่ามันจะพร้อม" ก็จะมีความรู้มากเกินไปของระบบ ThingBuilder ของคุณรู้เกี่ยวกับคุณสมบัติได้รับการแก้ไขอย่างลึกลับโดย InventoryManager และรู้เกี่ยวกับวัสดุ อย่าเห็นว่ามันลดความรู้ลง
user949300

@ user949300 ลองคิดดูว่าจะเป็นอย่างไรหากไม่มีตัวสร้างที่เดินทางข้ามระบบ คุณจะถูกบังคับให้ต้องเรียนในชั้นเรียนด้วยปัจจัยที่ทำให้แฟน ๆ ต้องตะลึงและนั่นเป็นสิ่งจำเป็นในการสร้างสิ่ง (แน่นอนว่าชั้นเรียนของคุณไม่ได้มีสมาธิกับความรู้ทั้งหมดนี่คือสิ่งที่เราต้องการหลีกเลี่ยงในตอนแรก) ตอนนี้ถ้าชั้นนี้มีความรับผิดชอบอื่น ๆ คุณกำลังสร้างชั้นเรียนขนาดใหญ่แบ่ง S ใน SOLID . หากนั่นเป็นความรับผิดชอบเพียงอย่างเดียวคุณกำลังทำให้ตัวเองเป็น ThingBuilder
อัลฟ่า

1

ขึ้นอยู่กับสิ่งที่คุณทำกับผู้สร้าง

หากคุณใช้เครื่องมือสร้างเพียงเพื่อตั้งค่า (และเปลี่ยนแปลง) คุณสมบัติของวัตถุและการสร้างวัตถุ (เลื่อน) มันสามารถถูกแทนที่ด้วยชื่อพารามิเตอร์

การแทนที่ตัวสร้างที่คุณอาจมีความสามารถในการอ่าน / การใช้งานที่ @Ixrec พูดถึง (หรืออาจไม่มีมันขึ้นอยู่กับสิ่งที่คุณกำลังทำกับผู้สร้าง)

อย่างไรก็ตามหากผู้สร้างของคุณทำมากกว่าแค่การถือครองทรัพย์สินและแต่ละขั้นตอนการก่อสร้างนั้นเกี่ยวข้องกับตรรกะก็ไม่สามารถแทนที่ได้

MockBuilderเป็นตัวอย่างที่ไม่สามารถแทนที่ด้วย params ชื่อ จากหน้า:

ไม่สามารถแทนที่ลอจิกในขั้นตอนการสร้างด้วย params ที่ระบุชื่อ


-5

รูปแบบการสร้างเป็นสิ่งสำคัญเมื่อทำงานกับวัตถุที่ไม่เปลี่ยนรูป มีประโยชน์มากมายในการทำงานกับวัตถุที่ไม่เปลี่ยนรูปโดยเฉพาะอย่างยิ่งในการทำให้โปรแกรมของคุณมีประสิทธิภาพมากขึ้นในสภาพแวดล้อมที่เกิดขึ้นพร้อมกัน (เช่นเธรด)


3
ใช่ผู้รับเหมานั้นยอดเยี่ยมสำหรับการทำงานกับวัตถุที่ไม่เปลี่ยนรูปแบบที่ซับซ้อน (หรือแม้แต่วัตถุที่เปลี่ยนแปลงไม่ได้ - คุณต้องตรวจสอบให้แน่ใจว่าวัตถุนั้นอยู่ในสถานะที่สอดคล้องกันก่อนจึงจะสามารถใช้งานได้) ที่กล่าวว่าnew Integer(42), new BigDecimal("42.000")และnew String("foobar")มีการก่อสร้างทั้งหมดเพื่อ immutables ว่า ... ดีผู้สร้างจะซับซ้อนจำเป็นสำหรับกรณีเหล่านี้ ดังนั้นผู้สร้างจึงไม่จำเป็นสำหรับการทำงานที่ไม่เปลี่ยนรูปเมื่อผู้สร้างสามารถทำงานได้เช่นกัน

ใช่นวกรรมิกสามารถใช้กับวัตถุที่ไม่เปลี่ยนรูปซึ่งไม่ได้ถูกปฏิเสธ แต่คำถามเดิมคือว่ารูปแบบของตัวสร้างนั้นมีการใช้งานจริงนอกเหนือจากอาร์กิวเมนต์ที่เป็นตัวเลือกหรือไม่และการตอบกลับของฉันคือการชี้แจงเรื่องนี้
codedabbler

2
คำถามเดิมบอกว่าไม่มีอะไรเกี่ยวกับวัตถุที่ไม่เปลี่ยนรูป มันถามเกี่ยวกับพารามิเตอร์ที่ตั้งชื่อและความสัมพันธ์กับพวกเขากับผู้สร้าง คำตอบของคุณเกี่ยวกับผู้สร้างและความสัมพันธ์กับวัตถุที่ไม่เปลี่ยนรูป ฉันมีเวลายากที่จะเห็นว่าคำตอบของคุณตอบคำถามอย่างไร
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.