คำถามติดแท็ก constructors

9
เหตุใดฉันจึงควรใช้คลาสโรงงานแทนการสร้างวัตถุโดยตรง
ฉันได้เห็นประวัติของโครงการห้องสมุดคลาสС # และ Java หลายรายการบน GitHub และ CodePlex และฉันเห็นแนวโน้มของการเปลี่ยนไปใช้คลาสของโรงงานซึ่งต่างจากการอินสแตนซ์วัตถุโดยตรง เหตุใดฉันจึงควรใช้คลาสของโรงงานอย่างกว้างขวาง ฉันมีห้องสมุดที่ค่อนข้างดีที่ซึ่งวัตถุต่าง ๆ ถูกสร้างขึ้นในแบบสมัยเก่า - โดยการเรียกใช้คลาสก่อสร้างสาธารณะ ในช่วงสุดท้ายผู้เขียนได้ทำการเปลี่ยนแปลงอย่างรวดเร็วของการสร้างสาธารณะทั้งหมดของหลายพันชั้นเรียนเป็นภายในและยังสร้างชั้นโรงงานขนาดใหญ่ที่มีCreateXXXวิธีการคงที่หลายพันที่เพียงแค่ส่งคืนวัตถุใหม่โดยการเรียกตัวสร้างภายในของชั้นเรียน API โครงการภายนอกใช้งานไม่ได้ เหตุใดการเปลี่ยนแปลงเช่นนี้จึงมีประโยชน์ อะไรคือประเด็นของการปรับโครงสร้างด้วยวิธีนี้ ประโยชน์ของการแทนที่การเรียกไปยังตัวสร้างคลาสสาธารณะด้วยการเรียกใช้เมธอดสแตติกจากโรงงานคืออะไร? ฉันควรใช้ช่างก่อสร้างสาธารณะเมื่อใดและฉันควรใช้โรงงานเมื่อใด

12
เคยมีเหตุผลในการทำงานของวัตถุทั้งหมดในนวกรรมิกหรือไม่?
ให้ฉันนำหน้าสิ่งนี้โดยบอกว่านี่ไม่ใช่รหัสของฉันหรือรหัสเพื่อนร่วมงานของฉัน หลายปีที่ผ่านมาเมื่อ บริษัท ของเรามีขนาดเล็กลงเรามีโครงการบางอย่างที่เราต้องการทำโดยที่เราไม่มีกำลังการผลิต ตอนนี้ฉันไม่มีอะไรกับผู้รับเหมาช่วงหรือผู้รับเหมาทั่วไป แต่ codebase ที่พวกเขาผลิตนั้นเป็นจำนวนมากของ WTF ที่ถูกกล่าวว่ามันทำงาน (ส่วนใหญ่) ดังนั้นฉันคิดว่ามันอยู่ใน 10 อันดับแรกของโครงการเอาต์ซอร์ซที่ฉันเคยเห็น ในขณะที่ บริษัท ของเราเติบโตขึ้นเราได้พยายามพัฒนาบ้านให้มากขึ้น โปรเจ็กต์นี้ลงบนตักของฉันดังนั้นฉันได้ไปทำความสะอาดเพิ่มการทดสอบ ฯลฯ ฯลฯ มีรูปแบบเดียวที่ฉันเห็นซ้ำหลายครั้งและดูเหมือนว่าน่ากลัวอย่างมากที่ฉันสงสัยว่าอาจจะมีเหตุผลและฉันแค่ไม่เห็นมัน รูปแบบเป็นวัตถุที่ไม่มีวิธีการสาธารณะหรือสมาชิกเพียงแค่ตัวสร้างสาธารณะที่ทำงานของวัตถุทั้งหมด ตัวอย่างเช่น (รหัสอยู่ใน Java หากมีความสำคัญ แต่ฉันหวังว่านี่จะเป็นคำถามทั่วไปมากขึ้น): public class Foo { private int bar; private String baz; public Foo(File f) { execute(f); } private void execute(File f) { // FTP …

7
การใช้“ ใหม่” ในตัวสร้างไม่ดีเสมอหรือไม่
ฉันได้อ่านว่าการใช้ "ใหม่" ในคอนสตรัคเตอร์ (สำหรับวัตถุอื่นที่ไม่ใช่วัตถุที่มีค่าอย่างง่าย) นั้นเป็นวิธีที่ไม่ดีเนื่องจากทำให้การทดสอบหน่วยเป็นไปไม่ได้ เนื่องจากฉันไม่ได้มีประสบการณ์จริงในการทดสอบหน่วยฉันพยายามรวบรวมกฎที่ฉันจะเรียนรู้ก่อน นอกจากนี้นี่เป็นกฎที่ใช้ได้โดยทั่วไปไม่ว่าจะใช้ภาษาใด

9
การตรวจสอบพารามิเตอร์ Constructor ใน C # - แนวปฏิบัติที่ดีที่สุด
แนวปฏิบัติที่ดีที่สุดสำหรับการตรวจสอบความถูกต้องของพารามิเตอร์คอนสตรัคเตอร์คืออะไร? สมมติว่า C # เป็นเรื่องง่าย: public class MyClass { public MyClass(string text) { if (String.IsNullOrEmpty(text)) throw new ArgumentException("Text cannot be empty"); // continue with normal construction } } มันจะเป็นที่ยอมรับที่จะโยนข้อยกเว้น? ทางเลือกที่ฉันพบคือการตรวจสอบความถูกต้องก่อนที่จะสร้างอินสแตนซ์: public class CallingClass { public MyClass MakeMyClass(string text) { if (String.IsNullOrEmpty(text)) { MessageBox.Show("Text cannot be empty"); return null; } else …

5
ฉันควรเริ่มต้น C structs ผ่านพารามิเตอร์หรือโดยค่าตอบแทน? [ปิด]
บริษัท ที่ฉันทำงานอยู่นั้นกำลังเริ่มต้นโครงสร้างข้อมูลทั้งหมดผ่านฟังก์ชันเตรียมใช้งานเช่น: //the structure typedef struct{ int a,b,c; } Foo; //the initialize function InitializeFoo(Foo* const foo){ foo->a = x; //derived here based on other data foo->b = y; //derived here based on other data foo->c = z; //derived here based on other data } //initializing the structure Foo foo; InitializeFoo(&foo); …

3
เป็นการ“ เริ่มต้น”“ วิ่ง” หรือ“ ดำเนินการ” เป็นวิธีปฏิบัติที่ดีหรือไม่?
ฉันกำลังทำงานบนฐานรหัสที่มีหลายคลาสที่ใช้วิธีการเริ่มต้น ดูเหมือนว่าการก่อสร้างแบบสองเฟสสำหรับฉันซึ่งฉันถือว่าเป็นการปฏิบัติที่ไม่ดีอยู่เสมอ ฉันไม่สามารถบอกความแตกต่างระหว่างสิ่งนี้กับตัวสร้างได้ เมื่อใดจึงเหมาะสมที่จะใช้วิธีการเริ่มต้นแทนการสร้างวัตถุปกติ เมื่อใดฉันจึงควรใช้ตัวสร้าง แก้ไข: ฉันไม่คิดว่ามันเป็นสิ่งที่เกี่ยวข้อง แต่ภาษาการเขียนโปรแกรมคือ C # ซึ่งสามารถนำไปใช้กับ Java หรือ C ++ ได้อย่างเท่าเทียมกัน

3
พารามิเตอร์ทางเลือกหรือตัวสร้างที่มากเกินไป
ฉันกำลังดำเนินการDelegateCommandและเมื่อฉันกำลังจะใช้ตัวสร้างฉันจะมาพร้อมกับสองตัวเลือกการออกแบบต่อไปนี้: 1: มีตัวสร้างโอเวอร์โหลดหลายตัว public DelegateCommand(Action<T> execute) : this(execute, null) { } public DelegateCommand(Action<T> execute, Func<T, bool> canExecute) { this.execute = execute; this.canExecute = canExecute; } 2: มีคอนสตรัคเตอร์เดียวเท่านั้นที่มีพารามิเตอร์เป็นตัวเลือก public DelegateCommand(Action<T> execute, Func<T, bool> canExecute = null) { this.execute = execute; this.canExecute = canExecute; } ฉันไม่รู้ว่าจะใช้อันไหนเพราะฉันไม่รู้ว่าข้อดี / ข้อเสียที่เป็นไปได้มาจากวิธีใดวิธีหนึ่งจากสองวิธีที่เสนอ ทั้งสองสามารถถูกเรียกเช่นนี้: var command = …

5
ทำไมมันไม่กลายเป็นรูปแบบทั่วไปในการใช้ตัวตั้งค่าในตัวสร้าง
อุปกรณ์เสริมและตัวดัดแปลง (aka setters and getters) มีประโยชน์ด้วยเหตุผลสามประการ: พวกเขา จำกัด การเข้าถึงตัวแปร ตัวอย่างเช่นตัวแปรสามารถเข้าถึงได้ แต่ไม่สามารถแก้ไขได้ พวกเขาตรวจสอบพารามิเตอร์ พวกเขาอาจทำให้เกิดผลข้างเคียง มหาวิทยาลัยหลักสูตรออนไลน์บทช่วยสอนบทความในบล็อกและตัวอย่างโค้ดบนเว็บล้วนเน้นหนักเกี่ยวกับความสำคัญของผู้เข้าถึงและผู้ดัดแปลงพวกเขาเกือบรู้สึกว่า "ต้องมี" สำหรับรหัสในปัจจุบัน ดังนั้นเราสามารถค้นหาได้แม้ว่าพวกเขาจะไม่ให้ค่าเพิ่มเติมใด ๆ เช่นรหัสด้านล่าง public class Cat { private int age; public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } } ดังที่ได้กล่าวมามันเป็นเรื่องธรรมดามากที่จะหาตัวดัดแปลงที่มีประโยชน์มากกว่าซึ่งตัวตรวจสอบความถูกต้องของพารามิเตอร์และส่งข้อยกเว้นหรือส่งคืนบูลีนหากมีการป้อนข้อมูลที่ไม่ถูกต้อง /** * Sets the age for …

4
ถูกต้องตามกฎหมาย "งานจริง" ในตัวสร้างหรือไม่?
ฉันทำงานเกี่ยวกับการออกแบบ แต่กดปุ่มสิ่งกีดขวางบนถนนต่อไป ฉันมีคลาสเฉพาะ (ModelDef) ที่เป็นหลักเจ้าของต้นไม้โหนดซับซ้อนที่สร้างขึ้นโดยการแยก XML schema (คิด DOM) ฉันต้องการปฏิบัติตามหลักการออกแบบที่ดี (SOLID) และตรวจสอบให้แน่ใจว่าระบบผลลัพธ์นั้นสามารถทดสอบได้ง่าย ฉันมีความตั้งใจที่จะใช้ DI เพื่อส่งผ่านการพึ่งพาในตัวสร้างของ ModelDef (เพื่อให้สามารถสลับสิ่งเหล่านี้ได้อย่างง่ายดายถ้าจำเป็นระหว่างการทดสอบ) แม้ว่าสิ่งที่ฉันกำลังดิ้นรนคือการสร้างทรีโหนด ต้นไม้นี้จะถูกสร้างขึ้นด้วยวัตถุ "ค่า" อย่างง่ายซึ่งไม่จำเป็นต้องทำการทดสอบอย่างอิสระ (อย่างไรก็ตามฉันยังอาจส่ง Abstract Factory ไปยัง ModelDef เพื่อช่วยในการสร้างวัตถุเหล่านี้) แต่ฉันอ่านต่อไปว่าคอนสตรัคเตอร์ไม่ควรทำงานจริงใด ๆ (เช่นFlaw: Constructor ทำงานจริง ) นี่เป็นเหตุผลที่เหมาะสมสำหรับฉันหาก "งานจริง" หมายถึงการสร้างวัตถุที่ต้องอาศัยน้ำหนักมากซึ่งในภายหลังอาจต้องการเริ่มต้นการทดสอบ (สิ่งเหล่านั้นควรถูกส่งผ่านทาง DI) แต่สิ่งที่เกี่ยวกับวัตถุค่าน้ำหนักเบาเช่นต้นไม้โหนดนี้ ต้องสร้างต้นไม้ที่ไหนสักแห่งใช่มั้ย ทำไมไม่สร้างผ่าน ModelDef (ใช้, พูด, buildNodeTree () วิธี)? ฉันไม่ต้องการสร้างทรีโหนดด้านนอกของ ModelDef แล้วผ่านมันใน …

5
คุณจะย่อยสลายนวกรรมิกได้อย่างไร?
ให้บอกว่าฉันมีคลาสศัตรูและตัวสร้างจะมีลักษณะดังนี้: public Enemy(String name, float width, float height, Vector2 position, float speed, int maxHp, int attackDamage, int defense... etc.){} สิ่งนี้ดูไม่ดีนักเนื่องจากตัวสร้างมีพารามิเตอร์มากมาย แต่เมื่อฉันสร้างอินสแตนซ์ของศัตรูฉันต้องระบุทุกสิ่งเหล่านี้ ฉันต้องการคุณลักษณะเหล่านี้ในคลาส Enemy เพื่อให้สามารถวนซ้ำรายการของพวกเขาและรับ / ตั้งค่าพารามิเตอร์เหล่านี้ ฉันคิดว่าอาจจะ subclassing Enemy เป็น EnemyB, EnemyA ในขณะที่ hardcoding maxHp ของพวกเขาและคุณลักษณะเฉพาะอื่น ๆ แต่จากนั้นฉันก็จะสูญเสียการเข้าถึงคุณลักษณะ hardcoded ของพวกเขาหากฉันต้องการย้ำผ่านรายการ EnemyA ของ EnemyA และ EnemyB EnemyC ของ) ฉันแค่พยายามเรียนรู้วิธีการเขียนโค้ดให้สะอาด ถ้ามันสร้างความแตกต่างฉันทำงานใน Java …

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

3
ความซับซ้อนของตัวสร้างควรจะเป็น
ฉันกำลังพูดคุยกับเพื่อนร่วมงานของฉันว่าคอนสตรัคเตอร์สามารถทำงานได้เท่าใด ฉันมีคลาส B ที่ต้องใช้วัตถุอื่นภายใน A. วัตถุ A เป็นหนึ่งในสมาชิกไม่กี่คนที่คลาส B ต้องการทำงาน วิธีการสาธารณะทั้งหมดขึ้นอยู่กับวัตถุภายใน A. ข้อมูลเกี่ยวกับวัตถุ A ถูกเก็บไว้ในฐานข้อมูลดังนั้นฉันจึงพยายามตรวจสอบและรับมันโดยดูจากฐานข้อมูลในตัวสร้าง เพื่อนร่วมงานของฉันชี้ให้เห็นว่าตัวสร้างไม่ควรทำงานมากไปกว่าการจับพารามิเตอร์คอนสตรัคเตอร์ เนื่องจากวิธีการสาธารณะทั้งหมดจะล้มเหลวอย่างไรก็ตามหากไม่พบวัตถุ A โดยใช้อินพุตไปยังตัวสร้างฉันจึงแย้งว่าแทนที่จะอนุญาตให้สร้างตัวอย่างและล้มเหลวในภายหลัง คนอื่นคิดอย่างไร ฉันใช้ C # หากสร้างความแตกต่าง การอ่านมีเหตุผลที่จะทำงานของวัตถุทั้งหมดในคอนสตรัคเตอร์หรือไม่? ฉันสงสัยว่าการดึงวัตถุ A โดยไปที่ DB เป็นส่วนหนึ่งของ "การเริ่มต้นอื่น ๆ ที่จำเป็นในการทำให้วัตถุพร้อมใช้งาน" เพราะหากผู้ใช้ส่งค่าผิดไปยังตัวสร้างฉันจะไม่สามารถใช้วิธีการสาธารณะใด ๆ ตัวสร้างควรสร้างอินสแตนซ์ของฟิลด์ของวัตถุและทำการเริ่มต้นอื่น ๆ ที่จำเป็นเพื่อทำให้วัตถุพร้อมใช้งาน โดยทั่วไปหมายถึงตัวสร้างมีขนาดเล็ก แต่มีสถานการณ์สมมติที่จะมีงานจำนวนมาก
18 c#  constructors 

1
มันเป็นเรื่องปกติไหมที่จะใช้ตัวสร้างปริยาย
ถามเฉพาะเกี่ยวกับตัวสร้างเริ่มต้น ระบุว่าตัวสร้างเริ่มต้นข้อมูลทั้งหมดสำหรับวัตถุถ้าฉันสร้างคลาสที่ไม่สามารถใช้โดยไม่ต้องเริ่มต้นที่เหมาะสมมันไม่ใช่กรณีที่นวกรรมิกเริ่มต้นไม่มีประโยชน์หรือไม่ พิจารณา: // A class for handling lines in a CSV file class CSV_Entry { private: unsigned num_entries; std::string string_version; std::vector<std::string> vector_version; ...etc public: CSV_Entry(); CSV_Entry(const std::string& src_line); // returns a vector copy of the original entry std::vector<std::string> get_vector_snapshot(); } int main( void ) { ...etc CSV_Entry example = …

3
วิธีการเก็บรักษาอาร์กิวเมนต์นับเป็นวิธีที่ต่ำและยังคงแยกการพึ่งพาของบุคคลที่สามได้อย่างไร
ฉันใช้ห้องสมุดบุคคลที่สาม พวกเขาส่งPOJOให้ฉันซึ่งอาจนำไปใช้ในจุดประสงค์และวัตถุประสงค์ของเราเช่นนี้: public class OurData { private String foo; private String bar; private String baz; private String quux; // A lot more than this // IMPORTANT: NOTE THAT THIS IS A PACKAGE PRIVATE CONSTRUCTOR OurData(/* I don't know what they do */) { // some stuff } public String getFoo() …

6
วิธีเขียน constructors ที่อาจไม่สามารถสร้างอินสแตนซ์ของวัตถุได้อย่างถูกต้อง
บางครั้งคุณต้องเขียนนวกรรมิกซึ่งอาจล้มเหลว เช่นสมมติว่าฉันต้องการยกตัวอย่างวัตถุที่มีเส้นทางไฟล์สิ่งที่ต้องการ obj = new Object("/home/user/foo_file") ตราบใดที่พา ธ ชี้ไปยังไฟล์ที่เหมาะสมทุกอย่างก็เรียบร้อย แต่ถ้าสตริงไม่ใช่เส้นทางที่ถูกต้องสิ่งที่ควรทำลาย แต่อย่างไร คุณสามารถ: โยนข้อยกเว้น คืนค่า null object (หากภาษาการเขียนโปรแกรมของคุณอนุญาตให้ constructors ส่งคืนค่า) ส่งคืนวัตถุที่ถูกต้อง แต่มีธงระบุว่าเส้นทางของมันไม่ได้ตั้งอย่างถูกต้อง (ugh) คนอื่น ๆ ? ฉันคิดว่า "แนวปฏิบัติที่ดีที่สุด" ของภาษาการเขียนโปรแกรมต่างๆจะใช้สิ่งนี้แตกต่างกัน เช่นฉันคิดว่า ObjC ชอบ (2) แต่จะไม่สามารถนำไปใช้ใน C ++ ได้ซึ่งตัวสร้างจะต้องมีค่าเป็นโมฆะเป็นชนิดส่งคืน ในกรณีนี้ฉันใช้ (1) ใช้ ในภาษาการเขียนโปรแกรมที่คุณเลือกคุณสามารถแสดงวิธีจัดการกับปัญหานี้และอธิบายว่าทำไม

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