คำถามติดแท็ก object-oriented-design

การออกแบบเชิงวัตถุเป็นกระบวนการของการวางแผนระบบการโต้ตอบวัตถุเพื่อการแก้ปัญหาซอฟต์แวร์

10
เราอยู่ได้โดยปราศจากสิ่งก่อสร้าง?
สมมติว่าด้วยเหตุผลบางอย่างวัตถุทั้งหมดจะถูกสร้างขึ้นด้วยวิธีนี้ $ obj = CLASS :: getInstance () จากนั้นเราฉีดการอ้างอิงโดยใช้ setters และทำการเริ่มต้นการเริ่มต้นโดยใช้ $ obj-> initInstance (); มีปัญหาหรือสถานการณ์จริงใดบ้างที่ไม่สามารถแก้ไขได้ถ้าเราจะไม่ใช้ตัวสร้างเลย Ps เหตุผลในการสร้างวัตถุด้วยวิธีนี้คือเราสามารถแทนที่คลาสใน getInstance () ตามกฎบางอย่าง ฉันทำงานใน PHP ถ้าเป็นเช่นนั้น

5
คลาสควรรู้เกี่ยวกับคลาสย่อยหรือไม่?
คลาสควรรู้เกี่ยวกับคลาสย่อยหรือไม่? คลาสควรทำสิ่งที่เฉพาะเจาะจงสำหรับคลาสย่อยที่กำหนดเช่น? สัญชาตญาณของฉันบอกฉันว่ามันเป็นการออกแบบที่ไม่ดีดูเหมือนว่าจะมีรูปแบบต่อต้านบางอย่าง

12
การออกแบบเชิงวัตถุ
สมมติว่าคุณมีสิ่งต่อไปนี้: +--------+ +------+ | Animal | | Food | +-+------+ +----+-+ ^ ^ | | | | +------+ +-------+ | Deer | | Grass | +------+ +-------+ DeerสืบทอดจากAnimalและสืบทอดจากGrassFood จนถึงตอนนี้ดีมาก AnimalวัตถุสามารถกินFoodวัตถุ ทีนี้ลองผสมกันหน่อย ช่วยเพิ่มซึ่งสืบทอดมาจากLionAnimal +--------+ +------+ | Animal | | Food | +-+-----++ +----+-+ ^ ^ ^ | | | | | …

6
วัตถุควรรู้รหัสของตัวเองหรือไม่?
obj.idดูเหมือนว่าค่อนข้างธรรมดาและดูเหมือนว่าจะตกอยู่ในช่วงของสิ่งที่วัตถุสามารถรู้เกี่ยวกับตัวเอง ฉันพบว่าตัวเองถามว่าทำไมวัตถุของฉันควรรู้รหัสของตัวเอง? ดูเหมือนจะไม่มีเหตุผลที่จะมีหรือไม่ หนึ่งในเหตุผลหลักสำหรับมันที่มีอยู่คือการดึงมันและดังนั้นที่เก็บของฉันจำเป็นต้องรู้และใช้เพื่อการโต้ตอบของฐานข้อมูล ฉันเคยพบปัญหาที่ฉันต้องการทำให้วัตถุเป็นอนุกรมกับ JSON สำหรับ RESTful API ซึ่ง ID ดูเหมือนจะไม่พอดีกับเพย์โหลด แต่มีเพียง URI และรวมไว้ในวัตถุทำให้ยากขึ้น วัตถุควรรู้ว่าเป็น id ของตัวเองหรือไม่? ทำไมหรือทำไมไม่? อัปเดต : ข้อกำหนด id: แอตทริบิวต์ตัวระบุบนวัตถุ ในแง่ฐานข้อมูลคีย์ตัวแทนไม่ได้เป็นคีย์ธรรมชาติ วัตถุ: เอนทิตีหรือวัตถุที่ระบุตัวตนไม่ซ้ำกันภายในระบบ

4
ใช้คลาสนามธรรมใน C # เป็นคำจำกัดความ
ในฐานะนักพัฒนา C ++ ฉันค่อนข้างคุ้นเคยกับไฟล์ส่วนหัว C ++ และพบว่ามีประโยชน์ในการมี "เอกสาร" ที่ถูกบังคับภายในโค้ด ฉันมักจะมีช่วงเวลาที่ไม่ดีเมื่อฉันต้องอ่านรหัส C # เพราะ: ฉันไม่มีแผนที่ทางจิตของชั้นเรียนที่ฉันทำงานด้วย สมมติว่าในฐานะวิศวกรซอฟต์แวร์ฉันกำลังออกแบบกรอบงานของโปรแกรม มันจะบ้าเกินกว่าที่จะนิยามว่าทุกคลาสเป็นคลาสที่ไม่มีการใช้งานแบบนามธรรมคล้ายกับสิ่งที่เราจะทำกับส่วนหัวของ C ++ และให้นักพัฒนาใช้มันได้หรือไม่ ฉันเดาว่าอาจมีสาเหตุบางอย่างที่ทำให้บางคนคิดว่านี่เป็นทางออกที่น่ากลัว แต่ฉันไม่แน่ใจ สิ่งใดที่เราจะต้องพิจารณาเพื่อหาทางแก้ปัญหาเช่นนี้?

9
เมื่อใดที่คุณควรใช้คลาสส่วนตัว / ชั้นใน
เพื่อชี้แจงสิ่งที่ฉันถามคือ public class A{ private/*or public*/ B b; } เมื่อเทียบกับ public class A{ private/*or public*/ class B{ .... } } ฉันสามารถนึกถึงเหตุผลบางอย่างที่จะใช้อย่างใดอย่างหนึ่ง แต่สิ่งที่ฉันอยากจะเห็นคือตัวอย่างที่น่าเชื่อถือที่แสดงให้เห็นว่าข้อดีและข้อเสียไม่ใช่แค่เรื่องวิชาการ

11
เมื่อใดที่คุณต้องการอ้างอิงสองรายการไปยังวัตถุเดียวกัน
ใน Java โดยเฉพาะ แต่มีแนวโน้มในภาษาอื่นเช่นกัน: เมื่อใดจะมีประโยชน์ที่จะมีสองการอ้างอิงไปยังวัตถุเดียวกัน ตัวอย่าง: Dog a = new Dog(); Dob b = a; มีสถานการณ์ที่สิ่งนี้จะเป็นประโยชน์หรือไม่? ทำไมนี้จะเป็นทางออกที่ต้องการที่จะใช้aเมื่อใดก็ตามที่คุณต้องการที่จะมีปฏิสัมพันธ์กับวัตถุที่แสดงโดยa?

3
การออกแบบที่ดีที่สุดสำหรับรูปแบบ Windows ที่จะแบ่งปันฟังก์ชั่นทั่วไป
ในอดีตที่ผ่านมาฉันเคยใช้การสืบทอดเพื่อให้สามารถขยายแบบฟอร์ม Windows ในแอปพลิเคชันของฉันได้ ถ้าแบบฟอร์มทั้งหมดของฉันมีตัวควบคุมงานศิลปะและฟังก์ชันการทำงานร่วมกันฉันจะสร้างแบบฟอร์มพื้นฐานที่ใช้ตัวควบคุมและฟังก์ชันการทำงานทั่วไปแล้วอนุญาตให้ตัวควบคุมอื่นสืบทอดจากแบบฟอร์มพื้นฐานนั้น อย่างไรก็ตามฉันพบปัญหาเล็กน้อยเกี่ยวกับการออกแบบ การควบคุมสามารถอยู่ในภาชนะหนึ่งครั้งเท่านั้นดังนั้นการควบคุมแบบคงที่ใด ๆ ที่คุณมีจะยุ่งยาก ตัวอย่างเช่นสมมติว่าคุณมีรูปแบบพื้นฐานที่เรียกว่า BaseForm ซึ่งมี TreeView ซึ่งคุณได้รับการป้องกันและคงที่เพื่อให้อินสแตนซ์อื่น ๆ (ที่ได้รับ) ของคลาสนี้ทั้งหมดสามารถแก้ไขและแสดง TreeView เดียวกันได้ สิ่งนี้จะไม่ทำงานสำหรับหลาย ๆ คลาสที่สืบทอดมาจาก BaseForm เนื่องจาก TreeView นั้นสามารถอยู่ในหนึ่งคอนเทนเนอร์ในแต่ละครั้งเท่านั้น มันน่าจะเป็นในรูปแบบสุดท้ายที่เริ่มต้น แม้ว่าทุกอินสแตนซ์สามารถแก้ไขการควบคุมได้ แต่จะแสดงในเวลาเดียวเท่านั้น แน่นอนว่ามีการแก้ไข แต่พวกมันน่าเกลียด (นี่ดูเหมือนจะเป็นการออกแบบที่แย่มากสำหรับฉันทำไมภาชนะบรรจุหลาย ๆ อันไม่สามารถเก็บพอยน์เตอร์ไปยังวัตถุเดียวกันได้อย่างไรก็ตามมันเป็นอย่างนั้น) สถานะระหว่างฟอร์มนั่นคือปุ่มสถานะข้อความป้ายกำกับ ฯลฯ ฉันต้องใช้ตัวแปรโกลบอลสำหรับและรีเซ็ตสถานะบนโหลด สิ่งนี้ไม่ได้รับการสนับสนุนโดยนักออกแบบของ Visual Studio เป็นอย่างดี มีการออกแบบที่ดีกว่า แต่ยังคงไว้ซึ่งการบำรุงรักษาที่ใช้ง่ายหรือไม่? หรือรูปแบบการสืบทอดยังคงเป็นวิธีที่ดีที่สุด? อัปเดต ฉันเปลี่ยนจากการดู MVC เป็น MVP เป็นรูปแบบการสังเกตการณ์เป็นรูปแบบกิจกรรม นี่คือสิ่งที่ฉันกำลังคิดอยู่ในขณะนี้โปรดวิจารณ์: …

3
ไม่ทำให้สมาชิกสาธารณะเสมือนหรือเป็นนามธรรม - จริงเหรอ?
ย้อนกลับไปในยุค 2000 เพื่อนร่วมงานคนหนึ่งของฉันบอกฉันว่ามันเป็นรูปแบบการต่อต้านเพื่อทำให้วิธีการสาธารณะเสมือนหรือนามธรรม ตัวอย่างเช่นเขาถือว่าคลาสเช่นนี้ไม่ได้ออกแบบมาอย่างดี: public abstract class PublicAbstractOrVirtual { public abstract void Method1(string argument); public virtual void Method2(string argument) { if (argument == null) throw new ArgumentNullException(nameof(argument)); // default implementation } } เขากล่าวว่า นักพัฒนาของคลาสที่ได้รับที่ใช้Method1และการแทนที่Method2มีการทำซ้ำการตรวจสอบอาร์กิวเมนต์ ในกรณีที่ผู้พัฒนาคลาสพื้นฐานตัดสินใจที่จะเพิ่มบางสิ่งรอบ ๆ ส่วนที่กำหนดเองได้Method1หรือMethod2ใหม่กว่าเขาจะไม่สามารถทำได้ เพื่อนร่วมงานของฉันเสนอวิธีการนี้แทน: public abstract class ProtectedAbstractOrVirtual { public void Method1(string argument) { if (argument …

9
init () มีวิธีการดมกลิ่นของรหัสหรือไม่?
มีวัตถุประสงค์ในการประกาศinit()วิธีการสำหรับประเภทใด ๆ ? ฉันไม่ได้ถามว่าเราควรจะต้องการinit()มากกว่านวกรรมิกหรือวิธีการหลีกเลี่ยงการประกาศinit() ฉันถามว่ามีเหตุผลใด ๆ ที่อยู่เบื้องหลังการประกาศinit()วิธีการ (ดูว่ามันเป็นเรื่องธรรมดา) หรือไม่ถ้ามันเป็นกลิ่นรหัสและควรหลีกเลี่ยง init()สำนวนเป็นเรื่องธรรมดามาก แต่ผมยังไม่เห็นประโยชน์ที่แท้จริงใด ๆ ฉันกำลังพูดถึงประเภทที่สนับสนุนการเริ่มต้นด้วยวิธีการ: class Demo { public void init() { //... } } สิ่งนี้จะใช้ในรหัสการผลิตเมื่อใด ฉันรู้สึกว่ามันอาจจะเป็นกลิ่นรหัสเพราะมันบอกว่านวกรรมิกไม่เริ่มต้นวัตถุอย่างสมบูรณ์ทำให้วัตถุที่สร้างขึ้นบางส่วน วัตถุไม่ควรมีอยู่หากไม่ได้ตั้งสถานะ นี่ทำให้ฉันเชื่อว่ามันอาจเป็นส่วนหนึ่งของเทคนิคบางชนิดที่ใช้เพื่อเพิ่มความเร็วในการผลิตในแง่ของการใช้งานระดับองค์กร มันเป็นเหตุผลเดียวที่ฉันคิดได้ว่ามีสำนวนแบบนี้ฉันไม่แน่ใจว่ามันจะมีประโยชน์อย่างไรถ้าเป็นเช่นนั้น

4
การมีตัวแปรอินสแตนซ์มากเกินไปนำไปสู่การทำซ้ำรหัสได้อย่างไร
ตามRefactoring เพื่อรูปแบบ : เมื่อคลาสพยายามทำมากเกินไปมันมักจะแสดงตัวแปรอินสแตนซ์มากเกินไป เมื่อคลาสมีตัวแปรอินสแตนซ์มากเกินไปรหัสที่ซ้ำกันจะไม่สามารถล้าหลังได้ การมีตัวแปรอินสแตนซ์มากเกินไปนำไปสู่การทำซ้ำรหัสได้อย่างไร

4
วิธีการสร้างรหัส OO ที่ดีขึ้นในแอปพลิเคชันที่ขับเคลื่อนด้วยฐานข้อมูลเชิงสัมพันธ์ซึ่งฐานข้อมูลนั้นได้รับการออกแบบไม่ดี
ฉันกำลังเขียนโปรแกรมเว็บ Java ที่ประกอบด้วยส่วนใหญ่ของหน้าคล้ายกันที่ทุกหน้ามีหลายตารางและตัวกรองที่ใช้กับตารางเหล่านั้น ข้อมูลในตารางเหล่านี้มาจากฐานข้อมูล SQL ฉันใช้ myBatis เป็น ORM ซึ่งอาจไม่ใช่ตัวเลือกที่ดีที่สุดในกรณีของฉันเนื่องจากฐานข้อมูลได้รับการออกแบบไม่ดีและ mybatis เป็นเครื่องมือที่มุ่งเน้นฐานข้อมูลมากขึ้น ฉันพบว่าฉันกำลังเขียนรหัสซ้ำกันมากมายเนื่องจากเนื่องจากการออกแบบที่ไม่ดีของฐานข้อมูลฉันต้องเขียนแบบสอบถามที่แตกต่างกันสำหรับสิ่งที่คล้ายกันเนื่องจากแบบสอบถามเหล่านั้นอาจแตกต่างกันมาก นั่นคือฉันไม่สามารถหาพารามิเตอร์ของแบบสอบถามได้อย่างง่ายดาย สิ่งนี้แพร่กระจายเข้าไปในรหัสของฉันและแทนที่จะเติมแถวในคอลัมน์ในตารางของฉันด้วยการวนรอบแบบง่ายฉันมีรหัสเช่น: ได้รับข้อมูล (p1, ... , ปี่); รับข้อมูลB (p1, ... , pi); รับข้อมูลC (p1, ... , pi); รับข้อมูลD (p1, ... , pi); ... และในไม่ช้านี้จะระเบิดเมื่อเรามีตารางที่แตกต่างกันและมีคอลัมน์ต่างกัน นอกจากนี้ยังเพิ่มความซับซ้อนให้กับความจริงที่ว่าฉันใช้ "ประตู" ซึ่งมีผลต่อการแมปวัตถุกับองค์ประกอบ html ในหน้าเว็บ ดังนั้นโค้ด Java ของฉันจึงกลายเป็นอะแดปเตอร์ระหว่างฐานข้อมูลและส่วนหน้าซึ่งทำให้ฉันสร้างการเดินสายจำนวนมากโค้ดสำเร็จรูปที่มีตรรกะบางอย่างแทรกอยู่ภายใน วิธีการแก้ปัญหาที่ถูกต้องจะห่อหุ้ม mappers ORM ด้วย extralayer …

7
ฉันควรสร้างอินเตอร์เฟสสำหรับวัตถุการถ่ายโอนข้อมูลหรือไม่
มันเป็นความคิดที่ดีหรือเป็นความคิดที่ดีที่จะสร้างส่วนต่อประสานสำหรับการถ่ายโอนข้อมูลวัตถุ? สมมติว่าวัตถุนั้นมักจะไม่แน่นอน แม้ว่าตัวอย่างของฉันจะเป็นภาษาจาวา แต่ก็ควรใช้กับภาษาอื่นที่มีแนวคิดคล้ายกัน interface DataTransferObject { String getName(); void setName(String name); } class RealDataTransferObject implements DataTransferObject { String name; String getName() { return name; } void setName(String name) { this.name = name; } } แน่นอนว่านี่เป็นตัวอย่างที่ง่ายในชีวิตจริงอาจมีหลายสาขา

1
เหตุใดเบอร์ทรานด์เมเยอร์จึงคิดว่าการแบ่งคลาสย่อยเป็นวิธีเดียวที่จะขยายโมดูล“ ปิด”?
ในการสร้างซอฟต์แวร์เชิงวัตถุของเมเยอร์(1988) เขาได้กำหนดหลักการเปิด / ปิดดังต่อไปนี้: โมดูลจะได้รับการกล่าวถึงว่าเป็นเปิดถ้ามันยังคงมีอยู่สำหรับส่วนขยาย ตัวอย่างเช่นควรเป็นไปได้ที่จะเพิ่มเขตข้อมูลลงในโครงสร้างข้อมูลที่มีอยู่หรือองค์ประกอบใหม่ในชุดของฟังก์ชันที่ดำเนินการ โมดูลจะถูกปิดหากมีการใช้งานโดยโมดูลอื่น นี่ถือว่าโมดูลนั้นได้รับการกำหนดรายละเอียดที่ดีและมีเสถียรภาพ (อินเทอร์เฟซในแง่ของการซ่อนข้อมูล) เขาพูดต่อไปว่า: หากคุณเปิดโมดูลอีกครั้งคุณจะต้องเปิดไคลเอนต์ทั้งหมดอีกครั้งเพื่ออัปเดตโมดูลเนื่องจากใช้รุ่นเก่า … [ปัญหานี้] เกิดขึ้นทุกครั้งที่โมดูลจะต้องถูกขยายโดยฟังก์ชั่นใหม่หรือองค์ประกอบข้อมูลทำให้เกิดการเปลี่ยนแปลงในไคลเอนต์ทั้งทางตรงและทางอ้อม ... ด้วยวิธีการคลาสสิกในการออกแบบและการเขียนโปรแกรมจึงไม่มีวิธีเขียนโมดูลที่เปิดและปิด วิธีการแก้ปัญหาของเมเยอร์ในภาวะที่กลืนไม่เข้าคายไม่ออกนี้คือ: ไม่ขยายโมดูลห้องสมุดโดยการปรับเปลี่ยนคลาสที่มีอยู่; ให้เขียนโมดูลใหม่แทนคลาสย่อยที่มีอยู่แล้วและให้ไคลเอนต์ใหม่พึ่งพาโมดูลใหม่นั้น ตอนนี้ในปี 1988 ฉันเขียนโปรแกรมของเล่น (ขั้นตอน) ใน Turbo Pascal และ Blankenship Basic และประสบการณ์ระดับมืออาชีพในศตวรรษที่ 21 ของฉันคือ JVM, CLR และในภาษาไดนามิกดังนั้นฉันจึงไม่รู้ว่า Meyer แปลว่าอะไร โดย "แนวทางคลาสสิคเพื่อการออกแบบและการเขียนโปรแกรม" ตัวอย่างหนึ่งที่เป็นรูปธรรมของเมเยอร์ที่ว่าทำไมโมดูลลูกค้าจึงต้องเปิดใหม่ (คำสั่งเปลี่ยนจากการแจงนับซึ่งขณะนี้มีสมาชิกมากขึ้นต้องใช้เคสมากขึ้น) ดูสมเหตุสมผลพอสมควร แต่เขาไม่เกือบยืนยันว่าทุกครั้งที่คุณเพิ่มฟังก์ชันการทำงาน โมดูลคุณต้องอัปเดตไคลเอ็นต์ทั้งหมด มีเหตุผลทางประวัติศาสตร์ที่การยืนยันนี้ดูเหมือนชัดเจนในปี 1988? พูดหรือไม่ว่าการเพิ่มฟังก์ชั่นหรือโครงสร้างข้อมูลไปยัง C static library …

6
การเขียนโปรแกรมเชิงฟังก์ชั่นช่วยเพิ่มช่องว่างระหว่างปัญหาและแนวทางแก้ไขหรือไม่ [ปิด]
ปิด คำถามนี้จะต้องมีมากขึ้นมุ่งเน้น ไม่ยอมรับคำตอบในขณะนี้ ต้องการปรับปรุงคำถามนี้หรือไม่ อัปเดตคำถามเพื่อให้มุ่งเน้นที่ปัญหาเดียวโดยแก้ไขโพสต์นี้ ปิดให้บริการใน4 ปีที่แล้ว เนื่องจากภาษาเครื่อง (เช่น0110101000110101) ภาษาคอมพิวเตอร์มีวิวัฒนาการโดยทั่วไปในรูปแบบที่เป็นนามธรรมสูงกว่าโดยทั่วไปทำให้ง่ายต่อการเข้าใจรหัสเมื่อมันถูกนำไปใช้กับปัญหา แอสเซมเบลอร์เป็นนามธรรมผ่านรหัสเครื่อง C เป็นนามธรรมเหนือแอสเซมเบลอร์ ฯลฯ การออกแบบเชิงวัตถุดูเหมือนว่าจะดีมากที่ช่วยให้เราสามารถจำลองปัญหาในแง่ของวัตถุเช่นปัญหาของระบบการลงทะเบียนหลักสูตรมหาวิทยาลัยสามารถทำแบบจำลองกับCourseชั้นStudentเรียนคลาส ฯลฯ จากนั้นเมื่อเราเขียนวิธีการแก้ปัญหา ในภาษา OO เรามีคลาสที่คล้ายกันซึ่งได้รับความรับผิดชอบและโดยทั่วไปมีประโยชน์สำหรับการออกแบบโดยเฉพาะอย่างยิ่งสำหรับการทำให้โค้ดเป็นโมดูล ถ้าฉันให้ปัญหานี้แก่ทีมอิสระ 10 คนที่แก้ปัญหาด้วยวิธี OO โดยทั่วไป 10 วิธีแก้ปัญหาจะมีชั้นเรียนที่เกี่ยวข้องกับปัญหาที่เหมือนกัน อาจมีความแตกต่างมากมายเมื่อคุณเริ่มมีเพศสัมพันธ์และการโต้ตอบของคลาสเหล่านั้นดังนั้นจึงไม่มีสิ่งเช่น "ศูนย์ช่องว่างการเป็นตัวแทน" ประสบการณ์การใช้งานฟังก์ชั่นการเขียนโปรแกรมของฉันมี จำกัด มาก (ไม่มีการใช้งานจริงในโลกมีเพียงโปรแกรมประเภท Hello World) ฉันล้มเหลวในการดูว่าภาษาดังกล่าวอนุญาตให้ทำแผนที่โซลูชั่น FP ได้อย่างง่ายดายเพื่อแก้ไขปัญหา (ด้วยช่องว่างที่เป็นตัวแทนต่ำ) ในแบบที่ภาษา OO ทำอย่างไร ฉันเข้าใจถึงข้อดีของ FP ที่เกี่ยวกับการเขียนโปรแกรมพร้อมกัน แต่ฉันขาดอะไรไปหรือ FP ไม่ได้ลดช่องว่างในการเป็นตัวแทน (ทำให้การแก้ปัญหาเข้าใจง่ายขึ้น)? อีกวิธีที่จะถามสิ่งนี้: …

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