วิธีการของโรงงานแบบคงที่คืออะไร?


261

"โรงงานคงที่" วิธีการคืออะไร?


วิธีการทางเลือกคงที่จากโรงงานใช้การฉีดแบบพึ่งพา
CMCDragonkai

1
@ThangPham คำตอบของ Jason Owen นั้นมีข้อผิดพลาดเพราะอ้างว่าจะพูดถึงรูปแบบวิธีการของโรงงานซึ่งแตกต่างจากรูปแบบวิธีการของโรงงานแบบคงที่ซึ่งจริงๆแล้วมันพูดถึง ดังนั้นในขณะที่มันทำงานได้ดีในการตอบคำถามจริงฉันไม่คิดว่ามันจะเป็นที่ยอมรับได้ในสถานะปัจจุบันเพราะมันนำมาซึ่งรูปแบบที่ไม่เกี่ยวข้องและเพิ่มความสับสนร่วมกันอย่างไม่น่าเชื่อเกี่ยวกับความแตกต่างระหว่างสองรูปแบบ
Theodore Murdock

@ CMCDragonkai ฉันคิดว่าการพึ่งพาการฉีดและโรงงานคงที่จะแตกต่างกัน โรงงานคงที่อาจจำเป็นต้องใช้แม้ในกรณีของการฉีดพึ่งพาสำหรับอินสแตนซ์ของการพึ่งพาที่จะฉีด
Karan Khanna

คำตอบ:


126

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

public class DbConnection{
   private static final int MAX_CONNS = 100;
   private static int totalConnections = 0;

   private static Set<DbConnection> availableConnections = new HashSet<DbConnection>();

   private DbConnection(){
     // ...
     totalConnections++;
   }

   public static DbConnection getDbConnection(){

     if(totalConnections < MAX_CONNS){
       return new DbConnection();

     }else if(availableConnections.size() > 0){
         DbConnection dbc = availableConnections.iterator().next();
         availableConnections.remove(dbc);
         return dbc;

     }else {
         throw new NoDbConnections();
     }
   }

   public static void returnDbConnection(DbConnection dbc){
     availableConnections.add(dbc);
     //...
   }
}

ถ้าฉันเข้าใจถูกต้องคุณสามารถเพิ่ม availableConnections.add (db) ให้กับ method returnDbConnection (DbConnection db) ได้หรือไม่?
Haifeng Zhang

@haifzhan มันไม่ได้ตั้งใจจะให้เสร็จสมบูรณ์ แต่ก็โอเค
Matthew Flaschen

@ MatthewFlaschen ควรลดการเชื่อมต่อทั้งหมดในขณะที่การเชื่อมต่อถูกส่งคืนหรือไม่
หินกลิ้ง

@Sridhar ไม่ใช่เป็นจำนวนการเชื่อมต่อที่มีอยู่ (ถูกติดตามเพื่อให้มากกว่า MAX_CONNS ไม่ได้ถูกสร้างขึ้น) ไม่ใช่จำนวนที่มีการหมุนเวียน
Matthew Flaschen

@MatthewFlaschen วิธีการของคุณจะถูกดักจับโดย sonarcube เป็นตัวบล็อกข้อผิดพลาดถ้า DbConnection ปิดได้
Awan Biru

477

โรงงานรูปแบบวิธีคงเป็นวิธีที่จะสร้างวัตถุแค็ปซูล หากไม่ใช้วิธีโรงงานคุณก็จะเรียกระดับของตัวสร้างFoo x = new Foo()โดยตรง: Foo x = Foo.create()ด้วยรูปแบบนี้คุณแทนจะเรียกวิธีโรงงาน: คอนสตรัคเตอร์ถูกทำเครื่องหมายว่าเป็นแบบส่วนตัวดังนั้นจึงไม่สามารถเรียกได้ยกเว้นจากภายในชั้นเรียนและวิธีการของโรงงานจะถูกทำเครื่องหมายstaticว่าสามารถเรียกได้โดยไม่ต้องมีวัตถุก่อน

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

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

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

Coordinate c = Coordinate.createFromCartesian(double x, double y)

และ

Coordinate c = Coordinate.createFromPolar(double distance, double angle)

สิ่งนี้สามารถใช้เพื่อปรับปรุงความสามารถในการอ่านเช่น Rasmus notes


32
โปรดทราบว่าวิธีโรงงานแบบคงที่ไม่เหมือนกับรูปแบบวิธีการโรงงานจากรูปแบบการออกแบบ [Gamma95, p 107] วิธีคงที่จากโรงงานที่อธิบายไว้ในรายการนี้ไม่มีเทียบเท่าโดยตรงในรูปแบบการออกแบบ
Josh Sunshine

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

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

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

1
โปรดทราบว่าตัวสร้างไม่จำเป็นต้องเป็นแบบส่วนตัว ชั้นสามารถให้ทั้งวิธีคงที่โรงงานสาธารณะและตัวสร้าง
Kevin

171

บันทึก! " วิธีการของโรงงานแบบคงที่นั้นไม่เหมือนกับรูปแบบวิธีการของโรงงาน " (c) Java ที่มีประสิทธิภาพ, Joshua Bloch

วิธีการจากโรงงาน: "กำหนดอินเทอร์เฟซสำหรับการสร้างวัตถุ แต่ให้คลาสที่ใช้อินเทอร์เฟซเป็นตัวตัดสินใจว่าคลาสใดที่จะสร้างอินสแตนซ์วิธีที่เป็นโรงงานจะทำให้คลาสเลื่อนการอินสแตนซ์

"วิธีการจากโรงงานแบบคงที่เป็นเพียงวิธีแบบคงที่ที่ส่งกลับอินสแตนซ์ของคลาส" (c) Java ที่มีประสิทธิภาพ, Joshua Bloch โดยปกติวิธีการนี้จะอยู่ในชั้นเรียนที่เฉพาะเจาะจง

ความแตกต่าง:

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

  • มูลค่าของ
  • getInstance
  • newInstance

คุณบอกความแตกต่างระหว่าง A () ใหม่กับ A.newInstance () ใหม่ได้ไหม และข้างใน A. ใหม่สิ่งที่เราควรทำอย่างไร
Shen

69

ความสามารถในการอ่านสามารถปรับปรุงได้โดยวิธีการคงที่จากโรงงาน

เปรียบเทียบ

public class Foo{
  public Foo(boolean withBar){
    //...
  }
}

//...

// What exactly does this mean?
Foo foo = new Foo(true);
// You have to lookup the documentation to be sure.
// Even if you remember that the boolean has something to do with a Bar
// you might not remember whether it specified withBar or withoutBar.

ถึง

public class Foo{
  public static Foo createWithBar(){
    //...
  }

  public static Foo createWithoutBar(){
    //...
  }
}

// ...

// This is much easier to read!
Foo foo = Foo.createWithBar();

ดังนั้นฉันจึงลองใช้ตัวอย่างคุณ แต่ฉันไม่แน่ใจว่ามันทำงานอย่างไร เป็นสองวิธี createWithBar และ createWithoutBar ควรจะเรียก 2 constructors ส่วนตัวภายในชั้น Foo?
Essej

@ แบ็กซ์เท็กซ์: ใช่ แต่ละคนจะเรียกคอนสตรัคเตอร์ส่วนตัว บางทีอาจจะเป็นเพียงแค่หนึ่งเดียวกัน: private Foo(boolean withBar){/*..*/} public static Foo createWithBar(){return new Foo(true);} public static Foo createWithoutBar(){return new Foo(false);}
Rasmus Faber

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

@Dherik: คุณควรใช้รูปแบบตัวสร้างแทน: FooBuilder ใหม่ (). withBar (). withoutFoo (). withBaz (). build ();
Rasmus Faber

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

จากhttp://www.javapractices.com/topic/TopicAction.do?Id=21


18

มันทั้งหมดลงไปสู่การบำรุงรักษา วิธีที่ดีที่สุดในการวางสิ่งนี้คือเมื่อใดก็ตามที่คุณใช้newคำสำคัญเพื่อสร้างวัตถุคุณกำลังเชื่อมโยงรหัสที่คุณเขียนไปยังการใช้งาน

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

โรงงานทุกวันนี้ส่วนใหญ่ได้รับความนิยมในการใช้ Dependency Injection เนื่องจากพวกเขาต้องการรหัสจานหม้อไอน้ำจำนวนมากซึ่งค่อนข้างยากที่จะรักษาตัวเอง การพึ่งพาการฉีดนั้นเทียบเท่ากับโรงงาน แต่ช่วยให้คุณสามารถระบุว่าวัตถุของคุณเชื่อมต่อเข้าด้วยกันอย่างไร (ผ่านการกำหนดค่าหรือคำอธิบายประกอบ)


3
คุณกำลังบอกว่าโรงงานต้องการความช่วยเหลือหรือไม่? ;)
John Farrell

4
ฮ่าฮ่า! ในวันนี้และอายุฉันคิดว่าพวกเราทุกคนสามารถใช้ bailout ... :)
30911 cwash cwash

11

ถ้า Constructor ของคลาสนั้นเป็นแบบส่วนตัวคุณจะไม่สามารถสร้างวัตถุสำหรับคลาสจากภายนอกได้

class Test{
 int x, y;
 private Test(){
  .......
  .......
  }
}

เราไม่สามารถสร้างวัตถุสำหรับชั้นเรียนด้านบนได้จากภายนอก ดังนั้นคุณไม่สามารถเข้าถึง x, y จากนอกชั้นเรียนได้ ถ้าอย่างนั้นการใช้คลาสนี้คืออะไร?
นี่คือคำตอบ: วิธีการโรงงาน
เพิ่มวิธีการด้านล่างในชั้นเรียนด้านบน

public static Test getObject(){
  return new Test();
}

ดังนั้นตอนนี้คุณสามารถสร้างวัตถุสำหรับคลาสนี้จากด้านนอก ชอบวิธี ...

Test t = Test.getObject();

ดังนั้นวิธีการคงซึ่งจะส่งกลับวัตถุของการเรียนโดยการดำเนินการคอนสตรัคส่วนตัวเรียกว่าเป็นโรงงาน
วิธี


1
ทำไมคุณถึงเรียกมันว่า "การแก้ปัญหา"? การประกาศตัวสร้างส่วนตัวไม่ใช่ "ปัญหา" มันเป็นรูปแบบการออกแบบ
Ojonugwa Jude Ochalifu

1
Updated ขอบคุณอยู่ดี
Santhosh

สวัสดี @ Sandosh ฉันมีความกังวลว่าทำไมคุณไม่ปล่อยให้คอนสตรัคเอกชนเป็นสาธารณะ? หากคุณไม่ต้องการสร้างคลาสย่อยมันดีสำหรับฉัน แต่ถ้าฉันไม่ต้องการสร้างคอนสตรัคเตอร์ส่วนตัวเราจะได้รับประโยชน์จากStatic Factory MethodConstructor สาธารณะหรือไม่?
Shen

9

ฉันคิดว่าฉันจะเพิ่มแสงให้กับโพสต์นี้ในสิ่งที่ฉันรู้ recent android projectเราใช้เทคนิคนี้อย่างกว้างขวางในของเรา แทนที่จะเป็นเช่นcreating objects using new operatorนั้นคุณสามารถใช้static methodเพื่อยกตัวอย่างชั้นเรียนได้ รายการรหัส:

//instantiating a class using constructor
Vinoth vin = new Vinoth(); 

//instantiating the class using static method
Class Vinoth{
  private Vinoth(){
  }
  // factory method to instantiate the class
  public static Vinoth getInstance(){
    if(someCondition)
        return new Vinoth();
  }
}

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

อีกตัวอย่างหนึ่งที่นำมาจากที่มีประสิทธิภาพ Java

public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
}

วิธีนี้แปลค่าดั้งเดิมบูลีนเป็นการอ้างอิงวัตถุบูลีน Boolean.valueOf(boolean)วิธีการแสดงให้เห็นถึงเราก็ไม่เคยสร้างวัตถุ ความสามารถในstatic factory methodsการส่งคืนออบเจ็กต์เดียวกันจากการทำซ้ำinvocationsอนุญาตให้คลาสรักษาการควบคุมอย่างเข้มงวดเกี่ยวกับอินสแตนซ์ที่มีอยู่ได้ตลอดเวลา

Static factory methodsคือการที่แตกต่างจากconstructorsที่พวกเขาสามารถกลับobjectใด ๆsubtypeจากประเภทนี้พวกเขากลับมา แอปพลิเคชันหนึ่งของความยืดหยุ่นนี้คือ API สามารถส่งคืนวัตถุโดยไม่ทำให้คลาสเป็นแบบสาธารณะ การซ่อนคลาสการใช้งานในลักษณะนี้นำไปสู่ ​​API ที่มีขนาดกะทัดรัดมาก

Calendar.getInstance () เป็นตัวอย่างที่ดีสำหรับการดังกล่าวข้างต้นมันจะสร้างขึ้นอยู่กับสถานที่เกิดเหตุBuddhistCalendar, หรือโดยหนึ่งเริ่มต้นJapaneseImperialCalendarGeorgian

อีกตัวอย่างที่ฉันคิดได้ก็คือSingleton patternที่คุณทำให้คอนสตรัคเตอร์ของคุณเป็นส่วนตัวสร้างgetInstanceวิธีการของตัวเองในแบบที่คุณแน่ใจว่ามีเพียงตัวอย่างเดียวเท่านั้น

public class Singleton{
    //initailzed during class loading
    private static final Singleton INSTANCE = new Singleton();

    //to prevent creating another instance of Singleton
    private Singleton(){}

    public static Singleton getSingleton(){
        return INSTANCE;
    }
}

4

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

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


สมมติว่าคุณให้โรงงานคืนประเภทอินเตอร์เฟสไม่ใช่คลาสคอนกรีตที่คุณติดต่อด้วย
Bill Lynch

1
คำตอบนี้เป็นเรื่องเกี่ยวกับรูปแบบการออกแบบวิธีการจากโรงงานไม่ใช่วิธีแบบคงที่จากโรงงาน วิธีการคงที่จากโรงงานเป็นเพียงวิธีคงที่สาธารณะที่ส่งกลับตัวอย่างของชั้นเรียน ดูบทที่ 2 ของ Java ที่มีประสิทธิภาพสำหรับรายละเอียดเพิ่มเติม
Josh Sunshine

4

ข้อดีอย่างหนึ่งที่เกิดขึ้นจากโรงงานแบบคงที่คือ API นั้นสามารถส่งคืนวัตถุได้โดยไม่ต้องเปิดเผยคลาสของตน สิ่งนี้นำไปสู่ ​​API ที่มีขนาดกะทัดรัดมาก ในจาวานี้สามารถทำได้โดยคลาส Collections ซึ่งซ่อนไว้ประมาณ 32 คลาสซึ่งทำให้ API คอลเลกชันมีขนาดเล็กมาก


2

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

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

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

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

เหตุผลที่ทำให้มันคงที่คือถ้าคุณต้องการติดตามทรัพยากรที่มีอยู่อย่าง จำกัด (จำนวนการเชื่อมต่อซ็อกเก็ตหรือการจัดการไฟล์) ดังนั้นคลาสนี้สามารถติดตามจำนวนที่ถูกส่งและส่งคืนดังนั้นคุณจึงไม่หมด ทรัพยากรที่ จำกัด


2

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

ความสามารถในการใช้วิธีคงที่จากโรงงานเพื่อส่งคืนวัตถุเดียวกันจากการเรียกใช้ซ้ำช่วยให้คลาสสามารถควบคุมอย่างเข้มงวดเกี่ยวกับอินสแตนซ์ที่มีอยู่ได้ตลอดเวลา คลาสที่ทำสิ่งนี้ถูกกล่าวเพื่อควบคุมอินสแตนซ์ มีเหตุผลหลายประการในการเขียนคลาสที่ควบคุมอินสแตนซ์ การควบคุมอินสแตนซ์อนุญาตให้คลาสรับประกันว่าเป็นซิงเกิลตัน (รายการ 3) หรือไม่มีค่าคงที่ (รายการ 4) นอกจากนี้ยังอนุญาตให้คลาสที่ไม่เปลี่ยนรูป (รายการ 15) เพื่อรับประกันว่าไม่มีสองอินสแตนซ์ที่เท่ากันอยู่: a.equals (b) ถ้าและถ้า a == b หากคลาสทำการรับประกันนี้ลูกค้าจะสามารถใช้ตัวดำเนินการ == แทนเมธอด equals (Object) ซึ่งอาจส่งผลให้ประสิทธิภาพดีขึ้น ประเภท Enum (รายการ 30) ให้การรับประกันนี้

จาก Effective Java, Joshua Bloch (รายการ 1, หน้า 6)


1

คงที่

สมาชิกที่ประกาศด้วยคำหลัก 'คงที่'

วิธีการของโรงงาน

วิธีการที่สร้างและส่งคืนวัตถุใหม่

ใน Java

ภาษาการเขียนโปรแกรมเกี่ยวข้องกับความหมายของ 'คงที่' แต่ไม่ตรงกับความหมายของ 'โรงงาน'


@Victor Responses ไม่จำเป็นต้องมีการโต้แย้ง ข้อเท็จจริงควรเพียงพอ: หากมีข้อโต้แย้งพวกเขาสามารถได้รับการสนับสนุนโดยการโต้แย้งหรือการอ้างอิง ฉันไม่ทราบว่ามีอะไรขัดแย้งที่นี่
มาร์ควิสแห่ง Lorne

ฉันระบุว่าเนื่องจากคำตอบสั้นเกินไปและไม่เข้าใจจริง ๆ ในตอนแรกลักษณะที่สองและสามดังนั้นจะขึ้นอยู่กับ OP เพื่อถาม ไม่เป็นไรฉันเปลี่ยนใจแล้วลองลบ downvote แต่ฉันทำไม่ได้
Victor

@Victor กำหนด 'สั้นเกินไป' บางครั้งคำตอบที่แท้จริงคือ 'ใช่', 'ไม่', 'ไม่' หรือ 'ทั้งสอง' 'สั้นเกินไป' เป็นอัตวิสัยทั้งหมด ฉันยังไม่เข้าใจความคิดเห็นดั้งเดิมของคุณ คุณไม่จำเป็นต้องมีอาร์กิวเมนต์เพื่อสนับสนุนคำจำกัดความ ตามคำจำกัดความ ฉันได้แก้ไขคำตอบของฉันดังนั้นตอนนี้จะเป็นไปได้ที่จะลบ downvote
มาร์ควิสแห่ง Lorne

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

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

1

การใช้งานจาวาประกอบด้วยคลาสยูทิลิตี้java.util.Arraysและjava.util.Collectionsทั้งคู่มีสแตติกเมธอดจากโรงงานตัวอย่างของมันและวิธีใช้:

  • Arrays.asList("1","2","3")

  • Collections.synchronizedList(..), Collections.emptyList(), Collections.unmodifiableList(...) (มีเพียงบางตัวอย่างเท่านั้นที่สามารถตรวจสอบ javadocs เพื่อดูตัวอย่างวิธีการได้ที่https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html )

ด้วย คลาสjava.lang.Stringมีวิธีการแบบคงที่จากโรงงานเช่น:

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