วิธีสร้างแบบคงที่ - ข้อดีข้อเสียเมื่อเปรียบเทียบกับตัวสร้าง


11

ข้อดีและข้อเสียของการมีวิธีสร้างวัตถุแบบสแตติกเหนือตัวสร้างคืออะไร

class Foo {
  private Foo(object arg) { }

  public static Foo Create(object arg) {
    if (!ValidateParam(arg)) { return null; }
    return new Foo(arg);
  }
}

ไม่กี่คนที่ฉันสามารถคิด:

ข้อดี:

  • ส่งคืน null แทนการโยนข้อยกเว้น (ตั้งชื่อTryCreate) สิ่งนี้สามารถทำให้รหัสสั้นลงและสะอาดยิ่งขึ้นในฝั่งไคลเอ็นต์ ลูกค้าไม่ค่อยคาดหวังว่านวกรรมิกจะล้มเหลว
  • สร้างวัตถุประเภทต่าง ๆ ด้วยความหมายที่ชัดเจนเช่นCreatFromName(String name)และCreateFromCsvLine(String csvLine)
  • สามารถส่งคืนวัตถุแคชหากจำเป็นหรือการใช้งานที่ได้รับมา

จุดด้อย:

  • ค้นพบน้อยลงและยากต่อการอ่านโค้ด
  • รูปแบบบางอย่างเช่นการจัดลำดับหรือการสะท้อนนั้นยากกว่า (เช่นActivator<Foo>.CreateInstance())

1
มันช้ากว่า คุณต้องจัดการกับการอ้างอิงที่ว่างเปล่าอยู่ดี
Amir Rezaei

1
@Air การจัดการ null คือ ( Foo x = Foo.TryCreate(); if (x == null) { ... }) การจัดการข้อยกเว้น ctor คือ ( Foo x; try { x = new Foo(); } catch (SomeException e) { ... }) เมื่อเรียกวิธีการปกติฉันชอบข้อยกเว้นรหัสข้อผิดพลาด แต่ด้วยการสร้างวัตถุTryCreateดูเหมือนสะอาดขึ้น
dbkk

ในการตรวจสอบของคุณจะทำการตรวจสอบทุกประเภทหรือไม่?
Amir Rezaei

สำหรับ Pro ตัวที่สอง "สร้างวัตถุประเภทต่างๆที่มีซีแมนทิกส์ชัดเจนเช่น CreatFromName (ชื่อ String) และ CreateFromCsvLine (String csvLine)" คุณอาจจะสร้างNameและCsvLineพิมพ์ได้ดีกว่าความต้องการโดยใช้ชื่อวิธีการ สิ่งนี้จะช่วยให้คุณสร้างได้มากเกินไป การใช้สตริงสำหรับทั้งคู่อาจถือได้ว่าเป็น "ความหลงใหลดั้งเดิม" (สมมติว่าคุณไม่ได้เลือกตัวเลือกนี้เนื่องจากเหตุผลด้านประสิทธิภาพที่ทราบ) ลองดูObject Calisthenicsเพื่อความสนุกในการสำรวจสิ่งนี้
bentayloruk

คำตอบ:


7

ข้อเสียเปรียบที่ใหญ่ที่สุดของ ' ผู้สร้าง ' คงที่อาจเป็นการ จำกัด การสืบทอด หากคุณหรือผู้ใช้ห้องสมุดของคุณมาจากคลาสของคุณFooก็Foo::Create()จะไร้ประโยชน์ Create()ตรรกะทั้งหมดที่กำหนดจะมีจะต้องมีการเขียนใหม่อีกครั้งในที่สืบทอดมา

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


1
ในทางปฏิบัติมันไม่ได้เป็นปัญหาเพราะชั้นเรียนส่วนใหญ่ไม่ได้รับการออกแบบมาให้สืบทอด (และควรปิดผนึก / สุดท้าย) หากในภายหลังปรากฎว่าคุณต้องการเปิดชั้นเรียนเป็นมรดกคุณสามารถย้ายตรรกะการเริ่มต้นใด ๆ ไปยังตัวสร้างที่มีการป้องกัน
Doval

7

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

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