"โรงงานคงที่" วิธีการคืออะไร?
"โรงงานคงที่" วิธีการคืออะไร?
คำตอบ:
เราหลีกเลี่ยงการให้การเข้าถึงโดยตรงกับการเชื่อมต่อฐานข้อมูลเพราะเป็นทรัพยากรที่เข้มข้น ดังนั้นเราจึงใช้วิธีการจากโรงงานแบบคง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);
//...
}
}
โรงงานรูปแบบวิธีคงเป็นวิธีที่จะสร้างวัตถุแค็ปซูล หากไม่ใช้วิธีโรงงานคุณก็จะเรียกระดับของตัวสร้าง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
บันทึก! " วิธีการของโรงงานแบบคงที่นั้นไม่เหมือนกับรูปแบบวิธีการของโรงงาน " (c) Java ที่มีประสิทธิภาพ, Joshua Bloch
วิธีการจากโรงงาน: "กำหนดอินเทอร์เฟซสำหรับการสร้างวัตถุ แต่ให้คลาสที่ใช้อินเทอร์เฟซเป็นตัวตัดสินใจว่าคลาสใดที่จะสร้างอินสแตนซ์วิธีที่เป็นโรงงานจะทำให้คลาสเลื่อนการอินสแตนซ์
"วิธีการจากโรงงานแบบคงที่เป็นเพียงวิธีแบบคงที่ที่ส่งกลับอินสแตนซ์ของคลาส" (c) Java ที่มีประสิทธิภาพ, Joshua Bloch โดยปกติวิธีการนี้จะอยู่ในชั้นเรียนที่เฉพาะเจาะจง
ความแตกต่าง:
แนวคิดหลักของวิธีการโรงงานแบบคงที่คือการได้รับการควบคุมการสร้างวัตถุและมอบหมายจากตัวสร้างวิธีการคงที่ การตัดสินใจของวัตถุที่จะสร้างเป็นเช่นในโรงงานนามธรรมทำนอกวิธีการ (ในกรณีทั่วไป แต่ไม่เสมอไป) ในขณะที่แนวคิดหลัก (!) ของวิธีการของโรงงานคือการมอบหมายการตัดสินใจว่าอินสแตนซ์ของคลาสใดที่จะสร้างภายในวิธีการของโรงงาน เช่นการใช้คลาสสิกซิงเกิลตันเป็นกรณีพิเศษของวิธีการคงโรงงาน ตัวอย่างวิธีการที่ใช้กันทั่วไปของโรงงานแบบคงที่:
ความสามารถในการอ่านสามารถปรับปรุงได้โดยวิธีการคงที่จากโรงงาน
เปรียบเทียบ
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();
private Foo(boolean withBar){/*..*/}
public static Foo createWithBar(){return new Foo(true);}
public static Foo createWithoutBar(){return new Foo(false);}
- มีชื่อซึ่งแตกต่างจากตัวสร้างซึ่งสามารถชี้แจงรหัส
- ไม่จำเป็นต้องสร้างวัตถุใหม่ในการร้องขอแต่ละครั้ง - วัตถุสามารถแคชและนำกลับมาใช้ใหม่ได้หากจำเป็น
- สามารถส่งคืนชนิดย่อยของชนิดส่งคืน - โดยเฉพาะสามารถส่งคืนออบเจกต์ที่คลาสการใช้งานไม่เป็นที่รู้จักสำหรับผู้โทร นี่เป็นคุณสมบัติที่มีค่าและใช้กันอย่างแพร่หลายในหลาย ๆ เฟรมเวิร์กซึ่งใช้อินเตอร์เฟสเป็นชนิดส่งคืนของวิธีการคงที่ของโรงงาน
มันทั้งหมดลงไปสู่การบำรุงรักษา วิธีที่ดีที่สุดในการวางสิ่งนี้คือเมื่อใดก็ตามที่คุณใช้new
คำสำคัญเพื่อสร้างวัตถุคุณกำลังเชื่อมโยงรหัสที่คุณเขียนไปยังการใช้งาน
รูปแบบจากโรงงานให้คุณแยกวิธีสร้างวัตถุจากสิ่งที่คุณทำกับวัตถุ เมื่อคุณสร้างวัตถุทั้งหมดของคุณโดยใช้ Constructor คุณจะต้องวางโค้ดที่ใช้วัตถุในการปรับใช้นั้น รหัสที่ใช้วัตถุของคุณคือ "ขึ้นอยู่กับ" วัตถุนั้น สิ่งนี้อาจไม่ดูเหมือนเป็นเรื่องใหญ่บนพื้นผิว แต่เมื่อวัตถุเปลี่ยน (คิดว่าการเปลี่ยนลายเซ็นของตัวสร้างหรือ subclassing วัตถุ) คุณต้องย้อนกลับไปและ rewire สิ่งทุกที่
โรงงานทุกวันนี้ส่วนใหญ่ได้รับความนิยมในการใช้ Dependency Injection เนื่องจากพวกเขาต้องการรหัสจานหม้อไอน้ำจำนวนมากซึ่งค่อนข้างยากที่จะรักษาตัวเอง การพึ่งพาการฉีดนั้นเทียบเท่ากับโรงงาน แต่ช่วยให้คุณสามารถระบุว่าวัตถุของคุณเชื่อมต่อเข้าด้วยกันอย่างไร (ผ่านการกำหนดค่าหรือคำอธิบายประกอบ)
ถ้า Constructor ของคลาสนั้นเป็นแบบส่วนตัวคุณจะไม่สามารถสร้างวัตถุสำหรับคลาสจากภายนอกได้
class Test{
int x, y;
private Test(){
.......
.......
}
}
เราไม่สามารถสร้างวัตถุสำหรับชั้นเรียนด้านบนได้จากภายนอก ดังนั้นคุณไม่สามารถเข้าถึง x, y จากนอกชั้นเรียนได้ ถ้าอย่างนั้นการใช้คลาสนี้คืออะไร?
นี่คือคำตอบ: วิธีการโรงงาน
เพิ่มวิธีการด้านล่างในชั้นเรียนด้านบน
public static Test getObject(){
return new Test();
}
ดังนั้นตอนนี้คุณสามารถสร้างวัตถุสำหรับคลาสนี้จากด้านนอก ชอบวิธี ...
Test t = Test.getObject();
ดังนั้นวิธีการคงซึ่งจะส่งกลับวัตถุของการเรียนโดยการดำเนินการคอนสตรัคส่วนตัวเรียกว่าเป็นโรงงาน
วิธี
Static Factory Method
Constructor สาธารณะหรือไม่?
ฉันคิดว่าฉันจะเพิ่มแสงให้กับโพสต์นี้ในสิ่งที่ฉันรู้ 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
, หรือโดยหนึ่งเริ่มต้นJapaneseImperialCalendar
Georgian
อีกตัวอย่างที่ฉันคิดได้ก็คือ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;
}
}
เมธอดจากโรงงานคือวิธีการที่ทำให้นามธรรมสร้างอินสแตนซ์ของวัตถุ โดยทั่วไปโรงงานจะมีประโยชน์เมื่อคุณรู้ว่าคุณต้องการอินสแตนซ์ใหม่ของคลาสที่ใช้อินเทอร์เฟซบางตัว แต่คุณไม่รู้จักคลาสที่ใช้งาน
สิ่งนี้มีประโยชน์เมื่อทำงานกับลำดับชั้นของคลาสที่เกี่ยวข้องตัวอย่างที่ดีของสิ่งนี้คือชุดเครื่องมือ GUI คุณสามารถเรียกรหัสยาก ๆ ไปที่ Constructor สำหรับการใช้งานที่เป็นรูปธรรมของแต่ละวิดเจ็ต แต่ถ้าคุณต้องการสลับชุดเครื่องมือหนึ่งไปยังอีกอันหนึ่งคุณจะต้องเปลี่ยนสถานที่มากมาย โดยใช้โรงงานคุณลดจำนวนรหัสคุณจะต้องเปลี่ยน
ข้อดีอย่างหนึ่งที่เกิดขึ้นจากโรงงานแบบคงที่คือ API นั้นสามารถส่งคืนวัตถุได้โดยไม่ต้องเปิดเผยคลาสของตน สิ่งนี้นำไปสู่ API ที่มีขนาดกะทัดรัดมาก ในจาวานี้สามารถทำได้โดยคลาส Collections ซึ่งซ่อนไว้ประมาณ 32 คลาสซึ่งทำให้ API คอลเลกชันมีขนาดเล็กมาก
วิธีการสร้างโรงงานแบบคงที่นั้นดีเมื่อคุณต้องการให้แน่ใจว่ามีเพียงหนึ่งอินสแตนซ์เดียวเท่านั้นที่จะส่งคืนคลาสคอนกรีตที่จะใช้
ตัวอย่างเช่นในคลาสการเชื่อมต่อฐานข้อมูลคุณอาจต้องการให้มีเพียงหนึ่งคลาสที่สร้างการเชื่อมต่อฐานข้อมูลดังนั้นหากคุณตัดสินใจที่จะเปลี่ยนจาก Mysql เป็น Oracle คุณสามารถเปลี่ยนตรรกะในชั้นเดียวได้และแอปพลิเคชั่นอื่น ๆ จะ ใช้การเชื่อมต่อใหม่
หากคุณต้องการใช้การรวมฐานข้อมูลก็จะเกิดขึ้นโดยไม่กระทบกับแอปพลิเคชั่นที่เหลือ
ปกป้องส่วนที่เหลือของแอปพลิเคชันจากการเปลี่ยนแปลงที่คุณอาจทำกับโรงงานซึ่งเป็นวัตถุประสงค์
เหตุผลที่ทำให้มันคงที่คือถ้าคุณต้องการติดตามทรัพยากรที่มีอยู่อย่าง จำกัด (จำนวนการเชื่อมต่อซ็อกเก็ตหรือการจัดการไฟล์) ดังนั้นคลาสนี้สามารถติดตามจำนวนที่ถูกส่งและส่งคืนดังนั้นคุณจึงไม่หมด ทรัพยากรที่ จำกัด
ข้อดีอย่างหนึ่งของวิธีการแบบสแตติกของโรงงานที่มีตัวสร้างส่วนตัว (การสร้างวัตถุต้องถูก จำกัด สำหรับคลาสภายนอกเพื่อให้แน่ใจว่าอินสแตนซ์จะไม่ถูกสร้างขึ้นภายนอก) คือคุณสามารถสร้างคลาสที่ควบคุมอินสแตนซ์ได้ และการเรียนเช่นควบคุมรับประกันได้ว่าไม่มีสองกรณีแตกต่างกันเท่ากันอยู่ ( a.equals (ข) และถ้าหาก == ข ) ในระหว่างโปรแกรมของคุณทำงานหมายความว่าคุณสามารถตรวจสอบความเท่าเทียมกันของวัตถุที่มี==ดำเนินการแทนเท่ากับวิธีการ ตามจาวาที่มีประสิทธิผล
ความสามารถในการใช้วิธีคงที่จากโรงงานเพื่อส่งคืนวัตถุเดียวกันจากการเรียกใช้ซ้ำช่วยให้คลาสสามารถควบคุมอย่างเข้มงวดเกี่ยวกับอินสแตนซ์ที่มีอยู่ได้ตลอดเวลา คลาสที่ทำสิ่งนี้ถูกกล่าวเพื่อควบคุมอินสแตนซ์ มีเหตุผลหลายประการในการเขียนคลาสที่ควบคุมอินสแตนซ์ การควบคุมอินสแตนซ์อนุญาตให้คลาสรับประกันว่าเป็นซิงเกิลตัน (รายการ 3) หรือไม่มีค่าคงที่ (รายการ 4) นอกจากนี้ยังอนุญาตให้คลาสที่ไม่เปลี่ยนรูป (รายการ 15) เพื่อรับประกันว่าไม่มีสองอินสแตนซ์ที่เท่ากันอยู่: a.equals (b) ถ้าและถ้า a == b หากคลาสทำการรับประกันนี้ลูกค้าจะสามารถใช้ตัวดำเนินการ == แทนเมธอด equals (Object) ซึ่งอาจส่งผลให้ประสิทธิภาพดีขึ้น ประเภท Enum (รายการ 30) ให้การรับประกันนี้
จาก Effective Java, Joshua Bloch (รายการ 1, หน้า 6)
คงที่
สมาชิกที่ประกาศด้วยคำหลัก 'คงที่'
วิธีการของโรงงาน
วิธีการที่สร้างและส่งคืนวัตถุใหม่
ใน Java
ภาษาการเขียนโปรแกรมเกี่ยวข้องกับความหมายของ 'คงที่' แต่ไม่ตรงกับความหมายของ 'โรงงาน'
การใช้งานจาวาประกอบด้วยคลาสยูทิลิตี้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(...)