การเขียนโปรแกรมเชิงวัตถุเป็นวิธีแก้ปัญหาที่ซับซ้อนหรือไม่? [ปิด]


18

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


15
งานเขียนเรียงความที่ยากลำบาก? ; p
glenatron

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

1
การเขียนโปรแกรมเชิงวัตถุเป็นเครื่องมือสำหรับการจัดการความซับซ้อน
Robert Harvey

คำถาม: คุณสามารถโปรแกรมปัญหาที่ซับซ้อนกับ OOP ได้หรือไม่? - คำตอบ: แน่นอน ถ้าคุณใช้ OOP มันจะซับซ้อน
mouviciel

"มันอาจจะเป็นความขัดแย้ง" ทำรายการการอภิปรายมากกว่าคำถามเทคนิค ...
jwenting

คำตอบ:


24

ไม่มีวิธีแก้ไขความซับซ้อน

ใน "The Mythical Man-Month", Fred Brooks กล่าวถึงความแตกต่างระหว่างความซับซ้อนโดยไม่ได้ตั้งใจและความสำคัญในการเขียนโปรแกรม ความซับซ้อนโดยบังเอิญนั้นเกิดจากเครื่องมือและวิธีการของเราเช่นต้องเขียนและทดสอบรหัสเพิ่มเติมในภาษาเพราะเราไม่สามารถแสดงความคิดเห็นของเราโดยตรงและสิ่งต่าง ๆ เช่นนั้น วิธีการและเทคนิคใหม่ ๆ สามารถลดความซับซ้อนโดยไม่ตั้งใจได้ ฉันสามารถเขียนโปรแกรมได้เร็วกว่าและดีกว่าเมื่อยี่สิบห้าปีที่แล้วเพราะฉันมีภาษาและเครื่องมือที่ดีกว่า

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

ดังนั้นเขาจึงอ้างว่าไม่มีกระสุนเงินการเขียนซอฟต์แวร์จะดำเนินต่อไปได้ยาก

ฉันขอแนะนำให้คุณอ่านหนังสือของเขา: โดยเฉพาะฉันแนะนำรุ่น Silver Anniversary พร้อมเรียงความเพิ่มเติม "No Silver Bullet" ในที่นี้เขาจะตรวจสอบการแก้ไขปัญหาที่นำเสนอเพื่อความซับซ้อนและพิจารณาผลกระทบของพวกเขา (สิ่งที่เขาพบว่ามีประสิทธิภาพมากที่สุดคือซอฟต์แวร์ห่อหดตัว - เขียนสิ่งที่ซับซ้อนเพียงครั้งเดียวและขายสำเนาเป็นพันหรือล้านชุด)

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


3
ฉบับครบรอบ 20 ปียังมี "No Silver Bullet 'Refired" ซึ่งเขาอ้างถึง OOP ว่าเป็น "bullet bullet" และกล่าวว่า: "... แนวคิดที่มีแนวโน้มมาก"
Jerry Coffin

18

ฉันคาดว่าคุณจะได้รับคำตอบที่ดีกว่าในไม่ช้า แต่นี่เป็นคำตอบที่ง่าย:

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

* เพราะไม่มีอะไรสามารถ 'แก้ปัญหา' ความซับซ้อนได้


4
นั่นเป็นวิธีที่ OOP ทำงานในเชิงทฤษฎี ในทางปฏิบัติตัวอย่าง OOP เช่นสุนัขที่เห่าเป็ดที่บินได้และรถบรรทุกที่เป็นยานพาหนะจะเริ่มพังทลายลงเมื่อคุณเขียนซอฟต์แวร์จริงเพราะวัตถุโปรแกรมจริงมักเป็นนามธรรมมากกว่านี้
Robert Harvey

8
@ Robert: ฉันไม่ได้ยืนยันว่าคุณจำลองแบบวัตถุในโลกแห่งความเป็นจริงใน OOP บ่อยครั้งเพียงแค่คิดว่ามันง่ายกว่าที่จะคิดถึงการเขียนโปรแกรมส่วนใหญ่ในแง่ของวัตถุ (แม้ว่าจะเป็นซ็อกเก็ตพร็อกซีและวัตถุจำลองด้านหน้า) เรามองโลกของสุนัขและเป็ดในชีวิตจริง
Fishtoaster

2
ไม่นี่เป็นความเข้าใจผิดทั่วไปเกี่ยวกับ OOP คุณไม่ควรจำลองโปรแกรมของคุณตามวัตถุในชีวิตจริง ไม่มีสิ่งเช่น BufferReader ในชีวิตจริง
hasen

1
@ Hasas j: ใช่นั่นคือสิ่งที่ฉันพูดเมื่อฉันชี้แจงในความคิดเห็นของฉัน
Fishtoaster

มีการพูดคุยที่ดีจริงๆที่programmers.stackexchange.com/questions/16189/…
Bill Michell

15

ฉันคิดว่านิยามกระแสหลักของ OOP ไม่ใช่ทางออกที่ดีสำหรับการจัดการความซับซ้อน

หากคุณกลับไปที่รากของมันฉันเชื่อว่า Alan Kay ได้รับอิทธิพลจาก "เสียงกระเพื่อม" อย่างมาก

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

หากคุณมองไปที่จุดสิ้นสุดของ "การบรรยาย 3a: ตัวอย่างของ Henderson Escher" ของSICP Hal Abelson เสนอว่าความซับซ้อนนั้นได้รับการจัดการโดยการแบ่งงานออกเป็นงานย่อยที่เล็กกว่า แต่โดยการสร้างเลเยอร์ของสิ่งที่เป็นนามธรรม ในระดับสูงสุดคุณแสดงวิธีแก้ปัญหาที่ซับซ้อนในแง่ของการแก้ปัญหาในระดับที่ต่ำกว่าของสิ่งที่เป็นนามธรรม

ฉันคิดว่า OOP เดิมทีมีจุดประสงค์เพื่อเป็นกลไกในการสร้างเลเยอร์ของนามธรรม

น่าเสียดายที่ทุกวันนี้ OOP คือ (ab) ใช้ในการเขียนรหัส / โครงสร้างสปาเก็ตตี้

ฉันจะสร้างตัวอย่าง: เกมผู้เล่นหลายคน FPS

ในระดับสูงสุดเกมทำงานโดยมีผู้เล่นหลายคนวิ่งไปรอบ ๆ แผนที่และยิงใส่กันโดยใช้อาวุธ

ในระดับที่ต่ำกว่าถัดไปเราต้องพูดถึงแผนที่และอาวุธและผู้เล่น บางทีเราสามารถพูดคุยเกี่ยวกับพวกเขาเป็นวัตถุทางกายภาพที่มีผลกระทบต่อโลกของเกม

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

และอื่น ๆ และอื่น ๆ.

สิ่งนี้หมายความว่า (และฉันเรียงลำดับจาก SICP .. ) คือว่าในแต่ละชั้นเราไม่เพียง แต่แก้ปัญหาเฉพาะอย่างใดอย่างหนึ่งเท่านั้น แต่ยังเป็นปัญหาอีกประเภทหนึ่งที่อยู่ในบริเวณใกล้เคียงของปัญหาที่เรา ' กำลังพยายามแก้ปัญหา ดังนั้นหากมีการเปลี่ยนแปลงเล็กน้อยในคำอธิบายปัญหาอาจเป็นเพียงการเปลี่ยนแปลงเล็กน้อยในโซลูชัน

ดังนั้นวิธีที่ฉลาดในการใช้ OOP คือการสร้างเลเยอร์ของ abstractions ในแต่ละระดับของนามธรรมคุณสามารถแก้ปัญหาโดยใช้ "วัตถุ" ในระดับที่อยู่ด้านล่าง

นี่คือบิตที่ฉันพูดถึงจากการบรรยาย: http://www.youtube.com/watch?v=CYtrfncMqHQ


5
เช่นเดียวกับเครื่องมือมากมาย OOP มีประสิทธิภาพสูงเมื่อใช้อย่างชาญฉลาดและไตร่ตรองและไม่ได้ผลเมื่อใช้งานในทางที่ผิด
Robert Harvey

1
+1 สำหรับ "เลเยอร์ของสิ่งที่เป็นนามธรรม" - คำอธิบายที่ดีมาก OOP ยังช่วยให้คุณสามารถ จำกัด ขอบเขตของสิ่งที่คุณเห็นกับวัตถุหนึ่งในแต่ละครั้งซึ่งทำให้ผู้คนมองเห็นการออกแบบและการโต้ตอบได้ง่ายขึ้น
Michael K

1
ฉันพบว่าความคิดที่ว่าแนวคิดเชิงทฤษฎีที่ไม่ "ถูกคอรัปชั่นโดยการใช้กระแสหลัก" จะทำให้การจัดการความซับซ้อนในโครงการในโลกแห่งความเป็นจริงดีขึ้น ... แปลกประหลาด
Michael Borgwardt

@MichaelBorgwardt การยอมรับหลักทำให้เกิดความคิดที่มีประโยชน์เพราะคนจำนวนมากในกระแสหลักไม่เข้าใจว่าความคิดนั้นเกี่ยวกับอะไรดังนั้นเมื่อคุณพยายามค้นหาว่า OOP คืออะไรคุณจะเห็นความเข้าใจที่คลาดเคลื่อนของคนหลากหลาย LISP ยังคงใช้อยู่แต่มีเพียงส่วนน้อยเท่านั้นดังนั้นจึงมีความเป็นไปได้น้อยที่ความคิดดั้งเดิมจะได้รับความเดือดร้อนจากการทุจริตที่เกิดจากหัวหน้าผู้มีผมหงุดหงิดไม่มีเงื่อนงำอะไรเกี่ยวกับมัน
hasen

@hasen j: OTOH เป็นไปได้มากว่า "ความคิดดั้งเดิม" ที่ไม่เคยเห็นการยอมรับเป็นหลักคือหอคอยงาช้างที่ไม่ทำงานในโลกแห่งความเป็นจริง การขาดความนิยมอย่างแน่นอนไม่ใช่จุดที่ชัดเจนในความโปรดปรานของอะไร
Michael Borgwardt

10

ตามปกติฉันไม่เห็นด้วยกับทุกคน นอกเหนือจากการให้เครื่องมือในการจัดการความซับซ้อนแล้ว OOP ยังสร้างความซับซ้อนเป็นจำนวนมากเนื่องจากเป็นกระบวนทัศน์ที่ไม่เพียงพอและไม่เหมาะสมทางคณิตศาสตร์ มันทำให้โปรแกรมเมอร์สับสนไม่มีที่สิ้นสุดเพื่อลองทำสิ่งต่าง ๆ ด้วย OOP ที่ไม่สามารถสร้างแบบจำลองด้วย OOP ได้

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

เมเยอร์จะได้รับการจัดเรียงวัตถุจากข้อกำหนดเหล่านี้เป็นตัวเป็นตนในไอเฟล Encapsulation จัดเตรียมการปิดการเปิดรับมรดกและ "สิ่ง" ที่กล่าวถึงคือคลาส

ฉันถือว่างานนี้เป็นวิทยาศาสตร์ที่ดีเพราะเมเยอร์นั้นผิดและเป็นไปได้เพราะคุณภาพงานของเขาที่จะระบุข้อผิดพลาดและแก้ไข

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

การแก้ปัญหาค่อนข้างชัดเจน หน่วยของโมดุลจะต้องมีขนาดใหญ่กว่าประเภทเดียว มันจะต้องประกอบด้วยหลายประเภทและวิธีการที่เกี่ยวข้อง

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

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

Standard Meta-Language (SML) และ Ocaml ขึ้นอยู่กับรุ่นนี้โดยตรง Ocaml ยังมีคลาสและ OOP: มันไม่ไร้ประโยชน์เพราะ OOP ให้คุณสมบัติในการจัดส่งหรือที่เรียกว่าไดนามิกผูกพัน อย่างไรก็ตามปัญหาในโลกแห่งความเป็นจริงส่วนใหญ่เกี่ยวข้องกับความสัมพันธ์และเป็นชั้นเรียนที่แทบไม่น่าแปลกใจที่ไม่ค่อยมีการใช้งานใน Ocaml มากนัก

มันเป็นเรื่องที่น่าประหลาดใจที่แทบจะไม่มีการใช้มรดกเลยในไลบรารีแม่แบบ C ++ มาตรฐาน

ความจริงง่ายๆคือ OOP ไม่ได้ให้เครื่องมือที่ถูกต้องในการจัดการความซับซ้อน แต่ก็ไม่ได้ให้เครื่องมือในการจัดการกับปัญหาที่เรียบง่าย แต่มันทำให้เข้าใจผิดและสับสนโปรแกรมเมอร์สองรุ่น นอกจากการช่วยเหลือแล้ว OOP ยังเป็นสิ่งเลวร้ายและเลวร้ายที่สุดที่เกิดขึ้นกับการเขียนโปรแกรมตั้งแต่ C, Fortran และ Cobol ก็เริ่มเบื่อ


อยากสร้างบัญชีอีกอันเพื่อโหวตคุณอีก;)
Marco Mariani

คุณยืนยันจำนวนมาก บางทีคุณอาจจะสามารถจัดหาข้อโต้แย้งสำรองการยืนยันของคุณหรือการอ้างอิงถึงข้อโต้แย้ง เช่นนี้ซึ่งไม่สนับสนุนวิทยานิพนธ์ต่าง ๆ ของคุณ (ในแง่ที่ว่า "มีสิ่งผิดปกติกับ OO นี่คือสิ่งที่ต้องทำ"): lucacardelli.name/Papers/BadPropertiesOfOO.pdf
Frank Shearar

3
การพูดว่า "foo เป็นสิ่งที่ชั่วร้ายที่สุดและเลวร้ายที่สุด ... " กัดกร่อนอย่างแข็งขันต่อการโต้แย้งใด ๆ ที่คุณอาจพยายามทำตามวิธี
Frank Shearar

6

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

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

http://en.wikipedia.org/wiki/Object-oriented_programming

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


2

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

นอกจากนี้ยังมีวิธีอื่นในการจัดการความซับซ้อนของซอฟต์แวร์เช่นการเขียนโปรแกรมลอจิก (Prolog) และการทำงาน (Haskell)

ในระดับที่สูงกว่าการเขียนโปรแกรมเราต้องการรูปแบบการออกแบบและหลักการเพื่อเป็นแนวทางใน OOP ดังนั้น OOP จึงจัดการความซับซ้อนในระดับต่ำ (การเข้ารหัส) ในขณะที่วิธีการเหล่านี้เช่น Design Patterns and Principles จะเป็นแนวทางในการออกแบบโซลูชันในระดับที่สูงขึ้น (ระบบและแอพพลิเคชั่น) และทำให้การพัฒนาซอฟต์แวร์และการจัดการ

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


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

2

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

ฉันชอบคำจำกัดความของ Eric Steven Raymond ในการเขียนโปรแกรม The Art of Unixเพราะมันอธิบายความซับซ้อนที่จำเป็นและไม่ได้ตั้งใจ http://www.faqs.org/docs/artu/ch13s01.html#id2964646

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


2

ปัญหาที่ซับซ้อนไม่สามารถแสดงได้ง่ายขึ้นผ่านเทคโนโลยี แต่สามารถจัดการได้ผ่านเทคโนโลยีเท่านั้น

OOP เป็นเทคโนโลยีแนวคิดและวิธีการแก้ไขปัญหา

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

โปรดทราบว่ามีแง่มุมอื่น ๆ ที่จะกำหนดความสำเร็จของโครงการของคุณ (เช่นรูปแบบการจัดการโครงการการกำหนดปัญหาการจัดการการเปลี่ยนแปลง ฯลฯ ... ) เทคโนโลยีที่คุณใช้นั้นมีความเกี่ยวข้องในความช่วยเหลือของคุณในการจัดการปัญหา

ในที่สุดการเขียนโปรแกรมเชิงวัตถุไม่สามารถแก้ปัญหาความซับซ้อนได้ เป็นเพียงเครื่องมือในการจัดการ (ถ้าใช้อย่างถูกต้อง)


+1 ในที่สุดการเขียนโปรแกรมเชิงวัตถุไม่สามารถแก้ปัญหาความซับซ้อนได้ เป็นเพียงเครื่องมือในการจัดการ (ถ้าใช้อย่างถูกต้อง)
Karthik Sreenivasan

2

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

โดยเฉพาะอย่างยิ่งมันมักจะเพิ่ม " ความซับซ้อนโดยบังเอิญ " จำนวนมาก ตัวอย่างคือความซับซ้อนโดยรอบการสืบทอดการใช้งานจำเป็นต้องมี "ฟังก์ชันมาตรฐาน" จำนวนมากซึ่งเท่ากับ () และ hashCode () เป็นต้นการนำเสนอที่ดีโดย Stuart Halloway ในหัวข้อนี้: " Simplicity Ain't Easy "

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


1

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

ดังที่กล่าวถึง C ++, OOP ให้เชือกเพียงพอที่จะแขวนตัวเอง


แต่นั่นเป็นเรื่องจริงสำหรับภาษาหรือกระบวนทัศน์ที่ทรงพลังใด ๆ คุณต้องการเชือกที่สั้นเกินกว่าจะแขวนตัวเองได้หรือไม่? คุณจะไม่มีทางขึ้นเขา!
Michael K

@Michael บางคนมากกว่าคนอื่น ๆ แต่เป็นหลักใช่ ไม่มีสัญลักษณ์แสดงหัวข้อย่อยเงินมีการดึงกลับไปที่ภาษาหรือกระบวนทัศน์ที่คุณใช้อยู่เสมอ
Dominique McDonnell

1

ฉันคิดว่าใช่เพราะมันช่วยให้คุณสามารถแบ่งความซับซ้อนออกเป็น "หน่วยการสร้าง" เล็ก ๆ ที่ซ่อนรายละเอียดจากนั้นใช้มันเพื่อสร้างฟังก์ชั่นที่คุณต้องการทีละขั้นตอนทีละชั้น

หารและพิชิต


1

OOP เป็นความพยายามในการแก้ปัญหา

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

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

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

ผลลัพธ์ที่ได้คือคุณต้องมีความซับซ้อนมากกว่าที่คุณต้องการ

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

จนกว่าคุณจะต้องรักษาบางสิ่งบางอย่างที่เขียนโดยคนอื่น

ใช่มันเป็นการดีที่จะรู้ว่าฟังก์ชั่นการเข้าถึงข้อมูลทั้งหมดอยู่ที่นี่ แต่สิ่งที่เรียกพวกเขา

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

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

มีคำศัพท์นี้: รหัสสปาเก็ตตี้

คุณจบลงด้วยระบบที่ซับซ้อนมากที่จำเป็นในการเขียนโค้ด ดังนั้น IDEs เช่น Visual Studio, Eclipse และ NetBeans ทั้งหมดนี้มีช่วงการเรียนรู้ที่สำคัญ อันที่จริงหลายคนสามารถสรุป / รวมเครื่องมือหลายอย่างที่พัฒนาโดยกลุ่มต่าง ๆ ซึ่งแต่ละอันมีเส้นโค้งการเรียนรู้ของตนเอง

นี่คือการจัดการความซับซ้อน?

การดีบักรหัสนั้นยากกว่าการเขียนถึงสองเท่า ขอให้โชคดีในการแก้ไขข้อบกพร่องบางอย่าง โดยเฉพาะอย่างยิ่งถ้ามันใช้หลาย ๆ ไลบรารี "เชื่อมโยงเข้าด้วยกัน" ณ รันไทม์โดยใช้ระบบฉีดพึ่งพาบางชนิด

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

IMHO มันขาดทุนสุทธิ มันเพิ่มความซับซ้อนมากกว่าที่จะกำจัด มันช่วยให้คุณทำสิ่งที่ยากเกินกว่าจะเป็นไปไม่ได้เลยหากปราศจากมัน แต่โครงการขนาดใหญ่ใด ๆ ที่พัฒนาอย่างรวดเร็วกลายเป็นความยุ่งเหยิงอย่างไม่มีที่ติ

หากคุณรู้วิธีการทำงานแล้วและคุณสามารถจำได้ว่าคุณอาจมีโอกาสได้รับการบำรุงรักษา

จำไว้ว่าให้ใช้กฎหมายของ Eagleson: รหัสใด ๆ ของคุณเองซึ่งคุณยังไม่ได้ดูในอีกหกเดือนอาจถูกเขียนโดยคนอื่น


0

ในระดับหนึ่ง ...

ทำไม? เพราะมันเอื้อต่อการแยกส่วนแบบตรรกะอย่างมาก อย่างน้อยเมื่อเปรียบเทียบกับการเขียนโปรแกรมตามขั้นตอนที่มันดึงดูดเกินกว่าที่จะเขียนโค้ดสปาเก็ตตี้จำนวนมาก


0

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

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

วิธีที่สามในการจัดการความซับซ้อนจะเป็นการเขียนโปรแกรมใช้งานได้และอาจจะมีวิธีการใหม่ ๆ ในอนาคตเช่นกัน


1
ลบความคิดเห็นแล้ว พยายามทำให้พวกเขาเป็นพลเรือน
Fishtoaster

0

ฉันคิดว่ามันเป็นทางออกของการบำรุงรักษามากกว่าเพราะในฐานะโปรแกรมเมอร์คุณควรจะวางวิธีการที่คุณมีข้อมูลเพื่อสร้างโมเดลวัตถุของแอปพลิเคชันของคุณ

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

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