ข้อดีของการโปรแกรมเชิงวัตถุ [ปิด]


35

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

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

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


2
Ooh คนดี - มันยากที่จะเกิดขึ้นกับคำจำกัดความที่ทุกคนที่กล่าวว่าพวกเขาทำ OOP จะเห็นด้วย! (แม้แต่ละเลยผู้ที่เพิ่งทำเช่นการเขียนโปรแกรมตามขั้นตอนในเสื้อผ้า OOP)
SamB

10
ดูเหมือนว่า "ฉันไม่ได้รับการเขียนโปรแกรม C เราแค่ใช้ภาษาแอสเซมบลีใช่ไหม" ถึงฉัน.
tia

2
@ โจเอล: ฉันไม่จำเป็นต้องรู้ว่าผู้สนับสนุนที่ไม่เป็นไปในลักษณะเดียวกับที่คุณทำ ถ้านั่นคือพื้นฐานของคุณคุณไม่เข้าใจว่ามันเพิ่มขึ้นอย่างไร ภาษาแรกของฉันคือ Applesoft BASIC และฉันได้เรียนรู้ภาษาเบสิกจำนวนหนึ่งรวมทั้ง C, Pascal และ x86 ชุดก่อนที่ฉันจะได้รู้จักกับ OOP โดย Delphi และ C ++ คนที่เคยประสบความแตกต่างนั้นสามารถอธิบายได้ดีกว่า
Mason Wheeler

3
ความคิดเห็นเชิงลบเพิ่มเติมเกี่ยวกับ OOP ที่นี่: harm.cat-v.org/software/OO_programmingรวมถึงคำพูดจาก Dijkstra และ Rob Pike
imgx64

3
@ Joel: คุณกดคัดค้านของฉันเพื่อ OOP บนหัว คนที่เป็น OOP คนที่นับถือทางเวทย์มนต์มักจะมีมุมมองฟางชายของการเขียนโปรแกรมขั้นตอนและมีประสบการณ์น้อยมากที่จะไม่มีกระบวนทัศน์อื่นใดเลย การเขียนโปรแกรมเชิงฟังก์ชั่นจะดูต่างไปจากเดิมอย่างสิ้นเชิง (หลักฐาน: นับจำนวนคนที่เพิ่งถามว่าจะทำคลาสและวัตถุใน Erlang ด้วยเหตุผลแปลก ๆ ได้อย่างไร) และการเขียนโปรแกรมเชิงตรรกะจะทำให้หัวของพวกเขาระเบิด ฉันสามารถจินตนาการได้ว่ากระบวนทัศน์ที่แปลกจริงบางอย่างจะทำอะไรกับพวกเขา ....
เพียงแค่ความคิดเห็นที่ถูกต้องของฉัน

คำตอบ:


7

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

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

นั่นคือสิ่งที่โปรแกรมขั้นตอนเป็นเหมือน

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

สำหรับข้อดีของการวางแนววัตถุบนซอฟต์แวร์ที่ไม่ใช่เชิงวัตถุ:

  • พฤติกรรมเฉพาะส่วนประกอบ - การทำรายละเอียดเกี่ยวกับวิธีการจัดการส่วนประกอบเฉพาะความรับผิดชอบของเครื่องเฉพาะส่วนประกอบขนาดเล็กช่วยให้มั่นใจได้ว่าทุกครั้งที่มีการจัดการส่วนประกอบเครื่องจะดำเนินการอย่างเหมาะสม
  • polymorphic expressions - เนื่องจากเครื่องจักรเฉพาะส่วนประกอบดำเนินการปรับแต่งให้เหมาะกับส่วนประกอบเฉพาะของมันข้อความเดียวกันที่ส่งไปยังเครื่องที่แตกต่างกันสามารถทำหน้าที่แตกต่างกันได้
  • type abstraction - มันมักจะเหมาะสมสำหรับส่วนประกอบหลายประเภทที่ใช้คำศัพท์เดียวกันสำหรับการทำงานของเครื่อง
  • การแยกข้อกังวลออกจากรายละเอียดเฉพาะส่วนประกอบไปยังเครื่องของพวกเขาหมายความว่าเครื่องกระบวนการต้องจัดการกับปัญหาทั่วไปที่กว้างกว่าและเกี่ยวข้องกับกระบวนการและข้อมูลที่จำเป็นในการจัดการ รวมทั้งมีโอกาสน้อยที่จะได้รับผลกระทบจากการเปลี่ยนแปลงในส่วนประกอบอื่น ๆ
  • ความสามารถในการปรับตัว - ส่วนประกอบที่มุ่งเน้นพื้นที่พิเศษของพวกเขาสามารถปรับให้เข้ากับการใช้งานที่ไม่คาดคิดได้ง่ายๆโดยการเปลี่ยนส่วนประกอบที่ใช้หรือทำให้มันพร้อมใช้งานกับเครื่องจักรกระบวนการอื่น
  • การนำโค้ดกลับมาใช้ใหม่ - ส่วนประกอบที่มีโฟกัสแคบและความสามารถในการปรับตัวที่มากขึ้นสามารถใช้ประโยชน์จากต้นทุนการพัฒนาของพวกเขาได้โดยการใช้งานบ่อยขึ้น

3
ทุกสิ่งที่คุณพูดดูเหมือนว่าจะนำไปใช้อย่างเท่าเทียมกันกับการเขียนโปรแกรมฟังก์ชั่นเน้นปัญหาที่นี่
Jesse Millikan

1
ยกเว้น OP ไม่ได้ถามเกี่ยวกับการเขียนโปรแกรมการใช้งานดังนั้นความคิดเห็นของคุณจึงไม่ดี โดยเฉพาะอย่างยิ่งตั้งแต่คำตอบของฉันเป็นที่ยอมรับ
Huperniketes

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

46

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

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

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

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

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

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

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

แก้ไข: เพื่อตอบสนองต่อคำถามของ Joel ในความคิดเห็น

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

ข้อจำกัดความรับผิดชอบเล็กน้อยที่นี่ โมเดลของฉันของ "โปรแกรมเชิงวัตถุ" นั้นเป็นแบบจำลองเดลฟี่ซึ่งคล้ายกับโมเดล C # /. NET มากเนื่องจากถูกสร้างขึ้นโดยอดีตสมาชิกทีมเดลฟาย สิ่งที่ฉันพูดที่นี่อาจใช้ไม่ได้หรือไม่ได้ใช้มากในภาษา OO อื่น ๆ

โปรแกรมเชิงวัตถุเป็นหนึ่งในตรรกะทั้งหมดที่มีโครงสร้างรอบวัตถุ ของหลักสูตรนี้จะต้องมีการ bootstrapped ที่ไหนสักแห่ง โปรแกรม Delphi Applicationของคุณโดยทั่วไปมีการเริ่มต้นรหัสที่สร้างวัตถุเดี่ยวที่เรียกว่า ที่จุดเริ่มต้นของโปรแกรมจะเรียกใช้Application.Initializeจากนั้นเรียกใช้Application.CreateFormสำหรับทุกรูปแบบที่คุณต้องการโหลดลงในหน่วยความจำตั้งแต่เริ่มต้นและจากนั้นApplication.Run,จะแสดงรูปแบบหลักบนหน้าจอและเริ่มการทำงานวนเข้า / เหตุการณ์ที่เป็นแกนหลักของ โปรแกรมคอมพิวเตอร์เชิงโต้ตอบ

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

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


4
ฉันคิดว่าคุณต้องตะปูบนหัวด้วยคำตอบนี้ เมื่อคุณสรุปการจัดการข้อมูล(ตกลงพวกเขากำลังจัดสรรตัวชี้ที่นี่แล้วเลื่อนบิตไปที่นั่นสองสามบิต ... )สิ่งที่เหลืออยู่คือตรรกะระดับสูงของโปรแกรม(ถ้าทำอย่างถูกต้องคุณสามารถเขียนโค้ดที่น่ากลัวในกระบวนทัศน์ใด ๆ .)
ChaosPandion

2
นั่นเป็นคำอธิบายที่ดีมากขอบคุณ คุณสามารถอธิบายสิ่งที่ "โปรแกรมเชิงวัตถุ" มี (นอกเหนือจากข้อบกพร่องแฟนซีเหล่านี้ที่คุณระบุไว้) ซึ่งแตกต่างจากโปรแกรมพื้นฐานที่จำเป็นหรือไม่ คุณจะ "รับลูกบอลกลิ้งได้อย่างไร"
Joel J. Adamson

1
+1: ฉันคิดว่าคุณได้รับจริง ๆ ด้วย "โดยทั่วไปแล้วมันพยายามทำสิ่งเดียวกันในระดับที่เล็กกว่า" โดยทั่วไปแล้วจะเป็นอีกระดับหนึ่งของสิ่งที่เป็นนามธรรม
n1ckp

1
@Karthik ปาร์ตี้ไปช้าไปหน่อย แต่จริงๆแล้วไม่ OOP ไม่จำเป็นต้องหมายถึงแค่นำคลาสมาใช้ซ้ำ แนวคิดทั้งหมดของระบบพิมพ์เป็นนามธรรมสำหรับการจัดกลุ่มวัตถุเข้าด้วยกันภายใต้อินเตอร์เฟสทั่วไป แต่คุณยังสามารถใช้ระบบที่ใช้ต้นแบบ (เช่น Javascript) โดยที่การเรียกเมธอดบนวัตถุจะแก้ปัญหาของเชนต้นแบบแทนที่จะเป็นคลาสเชน มันยังคงมีคุณสมบัติทั้งหมดของ OOP แต่อนุญาตให้วัตถุ ad-hoc และประเภทโดยเพียงแค่เพิ่มสิ่งใหม่ลงบนวัตถุที่มีอยู่ จากนั้นคุณสามารถโคลนวัตถุนั้นเพื่อรับชนิดใหม่นั้นมากขึ้น
CodexArcanum

2
+1 เพื่อชี้ให้เห็นข้อดีที่แท้จริงของ OOP "ที่เป็นแกนหลัก OOP เป็นวิธีการใช้กระบวนทัศน์ที่จำเป็นเพื่อจัดการความซับซ้อนระดับสูงได้ดียิ่งขึ้นโดยการสร้างโครงสร้างข้อมูล" อัจฉริยะ "ที่จำลองโดเมนปัญหา"
Karthik Sreenivasan

6

ฉันคิดว่า OOP นั้นเป็นเพียงชื่อที่มอบให้กับสิ่งที่คุณอาจถูกล่อลวงให้ทำตามวิธีที่ฉันเป็น

ย้อนกลับไปตอนที่ฉันยังเป็นโปรแกรมเมอร์เด็กถึงแม้จะอยู่ใน Fortran ก็มีสิ่งหนึ่งที่ชี้ไปที่รูทีนย่อย มันมีประโยชน์มากที่จะสามารถส่งตัวชี้ไปยังรูทีนย่อยเป็นอาร์กิวเมนต์ให้กับรูทีนย่อยอื่น

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

ฉันไม่แน่ใจว่าพวกเขาเคยสร้างสิ่งนั้นใน Fortran หรือไม่ แต่มันง่ายที่จะทำใน C และลูกหลานของมัน

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


5

มีระบบ OO หลากหลายประเภทและเป็นการยากที่จะให้คำจำกัดความที่ทุกคนเห็นด้วย แทนที่จะพยายามแสดงให้เห็นว่า OO ของ Java นั้นคล้ายคลึงกับระบบ Common Lisp Object อย่างไรฉันจะเริ่มด้วยการทำตามขั้นตอนทั่วไปมากกว่าทีละขั้นตอน

สมมติว่าคุณมีวัตถุจำนวนมากที่มีอยู่เป็นข้อมูลกระจัดกระจาย ตัวอย่างเช่นจุดอาจเป็นองค์ประกอบใน X, Y และอาร์เรย์ Z เพื่อพิจารณาจุดตัวเองก็จะทำให้ความรู้สึกที่จะดึงข้อมูลทั้งหมดเข้าด้วยกันเป็นสิ่งที่ต้องการ structC

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

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

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

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


3

OO มีคำจำกัดความต่าง ๆ มากมายใช่ ฉันแน่ใจว่าคุณสามารถพบสิ่งเหล่านี้ได้ด้วยตัวเอง โดยส่วนตัวแล้วฉันชอบRees Re: OOเป็นวิธีทำความเข้าใจกับพวกเขา ฉันเดาว่าคุณอ่านแล้วตั้งแต่คุณอ้าง Paul Graham (ฉันแนะนำให้ทุกคนที่สนใจ OO) ฉันจะใช้คำจำกัดความของ Java ที่นี่มากขึ้นหรือน้อยลงที่นี่ {1,2,3,7,8,9}

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

ฉันไม่คิดว่า OO มีประโยชน์มากขนาดเล็กพูดประมาณสองสามร้อยบรรทัด โดยเฉพาะอย่างยิ่งภาษา OO ที่ไม่มีอิทธิพลต่อฟังก์ชั่นการใช้งานที่ดีมักจะทำให้เจ็บปวดอย่างมากที่จะทำสิ่งต่าง ๆ ด้วยการรวบรวมหรือสิ่งที่ต้องการข้อมูลจำนวนมาก นี่คือสิ่งที่รูปแบบการออกแบบส่วนใหญ่เข้ามาเล่น; พวกเขากำลังวงโรคเอดส์ในพลังงานต่ำของภาษาพื้นฐาน

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

Java-ish OO เป็นวิธีการแก้ไขปัญหาเหล่านี้ที่ได้รับรางวัลการประกวดยอดนิยม เนื่องจากเป็นกลไกเดียวกับที่คน Java ใช้กับปัญหาขนาดเล็กที่สร้างขึ้นโดยภาษาที่มีอำนาจต่ำกว่าจึงมีแนวโน้มที่จะเริ่มมองหาวิธีการแก้ปัญหาที่วิเศษกว่าทุกอย่างมากกว่าเพียงแค่วิธีการจัดระเบียบ คนที่คุ้นเคยกับการเขียนโปรแกรมที่ใช้งานได้มักจะชอบโซลูชันอื่น ๆ เช่น CLOS หรือประเภทของ Haskell หรือเทมเพลต metaprogramming เมื่อติดอยู่ใน C ++ หรืออื่น ๆ (เช่นฉันทำงานทุกวันใน C #) ใช้ OO แต่ไม่ได้ตื่นเต้นกับมันเลย .


+1 - คำตอบที่ดี "ฉันไม่คิดว่า OO มีประโยชน์มากขนาดเล็ก"
Karthik Sreenivasan

ฉันยังอ่านบทความ ( dl.acm.org/citation.cfm?id=326103 ) ที่ระบุว่า OOP ไม่แสดงข้อได้เปรียบในการผลิตที่แท้จริงใด ๆ กับกระบวนการสำหรับผลิตภัณฑ์ซอฟต์แวร์สองรุ่นแรก เท่าที่ฉันเข้าใจเพียงเริ่มจากรุ่นที่สามคุณมีข้อได้เปรียบที่แท้จริงเพราะคุณสามารถนำโค้ด refactor / refactor ที่เขียนในสไตล์ OO ได้ดีกว่าในรูปแบบขั้นตอน
Giorgio

1

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

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

แต่รถไม่สามารถเคลื่อนที่ได้ด้วยตัวเองมันต้องการคนที่จะขับมัน - การมีปฏิสัมพันธ์ระหว่างวัตถุ


ฉันเข้าใจแล้ว: เหมาะสม อย่างไรก็ตามฉันคิดว่าหนึ่งในสิ่งที่เจ๋งจริงๆเกี่ยวกับการเขียนโปรแกรมคอมพิวเตอร์คือเราไม่ต้องคิดในแง่ที่ว่าวัตถุ "โลกแห่งความจริง" ทำอะไร ฉันคิดทางคณิตศาสตร์มากกว่า (ฉันเป็นนักคณิตศาสตร์ที่ทำการวิจัยชีววิทยา) นี่คือ "a-ha" (ความเข้าใจด้านสมาธิ) ไม่ใช่ทัศนคติที่เกิดขึ้นอย่างไรก็ตามมันมีผลกระทบอย่างมากกับวิธีการทำงานของฉัน
Joel J. Adamson

1

OOP = โครงสร้างข้อมูล + การส่งผ่านข้อความ + การสืบทอดซึ่งทั้งหมดเป็นการวิวัฒนาการเชิงตรรกะในโมเดลโปรแกรมมิง

สามารถเข้าใจ OOP (โดยโปรแกรมเมอร์) ในเวลาประมาณ 90 วินาที (ดูโปรไฟล์ของฉันสำหรับลิงก์) แนวคิดนั้นง่ายมาก

วิธีการสมัครเป็นเรื่องอื่น เพียงเพราะคุณรู้วิธีแกว่งค้อนไม่ได้หมายความว่าคุณรู้วิธีออกแบบและสร้างบ้าน ;-)


+1 - ฉันเห็นด้วย วิธีการใช้ OOP นั้นใช้เวลาและการฝึกฝนอย่างเงียบ ๆ แม้ว่าจะรู้เพียงว่าสิ่งที่พวกเขาไม่ได้ใช้เวลามากเพราะความหมายเป็นคำสำคัญที่นี่
Karthik Sreenivasan

0

ผมเขียนบล็อกโพสต์ในขณะที่ที่ผ่านมาว่าคุณอาจพบว่าเป็นประโยชน์: วิธีพิจารณาเทียบกับ OOP อธิบาย


ฉันไม่รู้ว่าทำไมคนลงคะแนนมัน! บทความนี้ดีกว่าแล้วพวกเหล่านี้ทั้งหมดเข้าด้วยกัน! คะแนนของฉันสำหรับ +1
Haris

คะแนนของมันลดลงเพราะมันเป็นลิงก์และเรียกใช้ซึ่งไม่สนับสนุนอย่างมาก ดูคำถามเมตาสแต็คโอเวอร์โฟลว์: คำตอบที่มีลิงค์อยู่ที่อื่นเป็น“ คำตอบที่ดี” หรือไม่?
icc97

0

วิธีที่ฉันเข้าใจเป็นครั้งแรก:

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

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


0

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

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

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

TL; DR: การเขียนโปรแกรม OO เป็นเหมือนการเขียนโปรแกรมแบบดั้งเดิมยกเว้นคุณจะมุ่งเน้นความพยายามในการกำหนดโครงสร้างข้อมูลให้มากขึ้นและคุณมีโครงสร้างข้อมูลที่สื่อสารกันผ่านตัวชี้ฟังก์ชัน


-1

ฉันคิดว่าหน้า Wikipedia เป็นสถานที่ที่ดีในการรับปัจจัยพื้นฐาน:
http://en.wikipedia.org/wiki/Object-oriented_programming

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

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

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


Downvoter สนใจที่จะให้เหตุผลหรือไม่?
RationalGeek

ดูเหมือนว่าคุณอาจยังไม่ได้อ่านคำถามทั้งหมดที่ถามมาซึ่งถูกกระตุ้นน้อยลงในรายการบล็อกที่ลิงก์ ผู้เขียนไม่ได้มีปัญหากับพื้นฐานเท่าที่ฉันสามารถบอกได้ ดังนั้นโดยทั่วไป -1 สำหรับการตอบคำถามที่คุณต้องการตอบมากกว่าคำถามที่ถูกถาม
Jesse Millikan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.