เราต้องการภาษา OO เพื่อจัดการความซับซ้อนของซอฟต์แวร์หรือไม่?


209

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

ในภาคการศึกษาแรกเราได้รับการแนะนำให้รู้จักกับแนวคิดของ OOP เช่นการห่อหุ้มการซ่อนข้อมูลการแยกส่วนการสืบทอดและอื่น ๆ ผ่านทาง Java และ UML (Java เป็นภาษาโปรแกรมแรกของฉัน)

วิธีที่ฉันเข้าใจ OOP เป็นวิธีจัดการความซับซ้อนของซอฟต์แวร์ แต่หลักการของมันไม่ได้ใหม่หรือไม่เหมือนใคร แต่เป็นหลักการที่เป็นสากลสำหรับสาขาวิศวกรรมทั้งหมด

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

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

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


41
คุณขาดการแยกส่วนต่อประสานและการนำไปใช้งาน ความสามารถในการสลับการใช้งานหนึ่งไปยังอีกการทำงานในขณะทำงานเป็นคุณสมบัติที่สำคัญ โดยพื้นฐานแล้วสิ่งนี้สามารถทำได้โดยวิธีการแบบไดนามิกของภาษา OO ที่มีการสืบทอด ภาษาเชิงปฏิบัติก็สามารถทำเช่นนั้นได้เช่นกัน (อ่าน: ตัวชี้โมฆะ) แต่ไม่มีความปลอดภัยประเภท
marstato

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

14
@ RobbieDee คุณอ่านคำถามของฉันจริงหรือไม่ มันเกี่ยวกับการพยายามที่จะเข้าใจ OO ในระดับพื้นฐานมากขึ้นโดยการตั้งคำถามสภาพอากาศความซับซ้อนของซอฟต์แวร์สามารถจัดการได้โดยไม่ต้อง OO ฉันไม่พยายามบ่อนทำลาย OO ไม่พยายามคิดค้นสิ่งใหม่ฉันแค่พยายามทำความเข้าใจให้ดีขึ้นและถ้าเป็นคำถามที่ 'ชัดเจนในตัวเอง' ทำไมถึงได้รับคำตอบที่ยอดเยี่ยมจาก Jorg?
steakexchange

12
การเข้ารหัสไฟล์ไม่ใช่การห่อหุ้ม คุณอาจบดบังการดูเนื้อหาของรหัสจากผู้พัฒนารายอื่น แต่คุณไม่จำเป็นต้องปกป้องการทำงานภายในของรหัสจากรหัสอื่น ผู้เขียนต้นฉบับสามารถทำสิ่งนี้ก่อนหรือหลังการเข้ารหัสหากเขาสามารถจำได้ว่า
JeffO

8
คุณไม่ต้องการอะไรนอกเหนือจากภาษาเครื่อง - ให้โปรแกรมเมอร์จดจำ opcodes และเขียนค่าและเลขศูนย์เอง แต่การมีภาษา "สัญลักษณ์" บางอย่างนั้นมีประโยชน์มากในแง่ของการลดข้อผิดพลาดและเพิ่มประสิทธิภาพการผลิตและตามที่ Dijkstra สังเกตภาษาที่กำหนด "โครงสร้าง" บางอย่าง (หรืออย่างน้อยก็ทำให้การบำรุงรักษา "โครงสร้าง" ง่ายขึ้น) ช่วยได้มาก ภาษา OO อาจไม่ใช่เทคโนโลยีในอุดมคติเนื่องจากระดับความซับซ้อนทางภาษาในปัจจุบัน แต่ก็ค่อนข้างดีสำหรับแอพพลิเคชั่นมากมาย ความคิดคือการจัดการความซับซ้อนโดยไม่ได้รับในทางของคุณ
Daniel R Hicks

คำตอบ:


177

ให้ฉันลองตอบคำถามทฤษฎีต่ำมาก :)

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

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

ตัวอย่างเช่นสมมติว่าฉันสร้าง a MagicButtonและ a MagicSliderซึ่งสามารถใช้ในระบบส่วนต่อประสานผู้ใช้ ฉันต้องการวิธีการจัดกลุ่มวิธีการที่สามารถใช้กับ MagicButton วิธีการที่สามารถใช้ได้กับ MagicSlider เท่านั้นและวิธีการที่ทั้งสองสามารถใช้ได้ วัตถุเหล่านี้แบ่งปันวิธีการบางอย่างเพราะพวกเขาทั้งสองวัตถุเวทมนตร์กุย

ฉันสามารถทำการจัดกลุ่มด้วยการตั้งชื่อฟังก์ชั่นในวิธีพิเศษMagicSlider_DoSomething ...โดยรวมวิธีการในไฟล์เฉพาะที่ตั้งชื่อด้วยวิธีพิเศษMagicSliderMethods.XXXหรือฉันสามารถหาวิธีพิเศษอื่น ๆ เพื่อทำสิ่งเดียวกัน หากไม่มีวิธีมาตรฐานในภาษาที่จะทำฉันจะทำมันแตกต่างจากคุณและแตกต่างจากคนอื่น ทำให้การแบ่งปันรหัสทำได้ยากขึ้น

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

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

นอกจากนี้: การมี abstractions ในภาษาช่วยให้โค้ดโค้ดขั้นสูงเช่น Eclipse ทำการวิเคราะห์สแตติกจำนวนมากบนโค้ด ตัวอย่างเช่น Eclipse สามารถเสนอรายการของวิธีการทั้งหมดที่สามารถใช้กับวัตถุได้เช่นเดียวกับการใช้งานอัตโนมัติของวิธีการ "สิ่งที่ต้องทำ" ที่ว่างเปล่า Eclispe รู้วิธีการที่คลาสของคุณต้องใช้โดยขึ้นอยู่กับว่าคุณขยายคลาสใดและอินเทอร์เฟซใดที่คุณใช้ นี่คงเป็นไปไม่ได้เลยหากไม่มีมาตรฐานภาษาที่จะทำ OO


40
ตัวอย่างคลาสสิก: ลัวะ มันไม่ได้เป็นแบบ OO แต่สามารถทำได้ แต่นี่หมายความว่ามีไลบรารี OO ที่รู้จักกันดีประมาณ 5 อันที่ไม่สามารถทำงานร่วมกันได้ทั้งหมด
Kroltan

55
@ steakexchange คุณให้ความสำคัญกับความสมบูรณ์มากเกินไป น้อยมากมี "จุดประสงค์เดียว" ภาษาต่าง ๆ ทำสิ่งต่าง ๆ มากมายเพื่อระดับคุณภาพที่แตกต่างกัน การเลือกภาษาคือการเลือกชุดของการแลกเปลี่ยนที่ทำให้เหมาะสมที่สุดสำหรับวัตถุประสงค์ที่คุณต้องการ
ทิม B

42
@nocomprende abstractions การทำให้เป็นมาตรฐานนั้นแท้จริงแล้วภาษาโปรแกรมนั้นมีไว้เพื่ออะไร แม้ภาษาแอสเซมบลีจะย่อความแตกต่างของสิ่งต่าง ๆ เช่นสิบฮาร์ดแวร์ในทศวรรษและครึ่ง
David Moles

56
@DavidMoles abstractions ที่ได้มาตรฐานเป็น อักษรภาษาโปรแกรมอะไร อย่าเสียโอกาสที่ดีในการใช้ "อักษร" อย่างแท้จริง!
Clement Cherlin

12
เป็นไปได้ที่จะสร้างมาตรฐานนี้ เมื่อฉันกลับมาอยู่ในช่วงกลางทศวรรษที่ 90 ฉันทำงานจำนวนมากใน X-Windows (ส่วนใหญ่ใช้ Motif สำหรับผู้ที่จำสิ่งต่าง ๆ ) X-Windows ช่วยให้คุณสามารถใช้คุณสมบัติทั้งหมดของการวางแนววัตถุใน C ปกติได้ ยิมนาสติกทางจิตที่ทำเช่นนั้นมีเนื้อหาค่อนข้างมากและเป็นที่พึ่งของผู้คนที่ไม่ได้มองเข้าไปในกล่อง (ณ จุดนี้รหัส Widget ของ Schroedinger โดยทั่วไปมักจะตายไปแล้ว) ภาษา OO ปกปิดสิ่งนี้จากตัวแปลงสัญญาณในลักษณะเดียวกับที่คอมไพเลอร์ปกติทำเพื่อผู้ประกอบและชีวิตจะง่ายขึ้น
เกรแฮม

211

ในภาคการศึกษาแรกเราได้รับการแนะนำให้รู้จักกับแนวคิดของ OOP เช่นการห่อหุ้มการซ่อนข้อมูลการแยกส่วนการสืบทอดและอื่น ๆ ผ่านทาง Java และ UML (Java เป็นภาษาโปรแกรมแรกของฉัน)

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

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

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

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

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

สิ่งนี้มีความหมายว่าใน Java ชั้นเรียนไม่ได้มุ่งเน้นวัตถุ สองอินสแตนซ์ของคลาสเดียวกันสามารถเข้าถึงการเป็นตัวแทนของกันและกันและการใช้งานส่วนตัว ดังนั้นอินสแตนซ์ของคลาสไม่ใช่วัตถุ แต่เป็นอินสแตนซ์ ADT จริง interfaceอย่างไรก็ตามJava จะให้ข้อมูลเชิงวัตถุที่เป็นนามธรรม ดังนั้นในคำอื่น ๆ : อินสแตนซ์ของอินเทอร์เฟซเท่านั้นเป็นวัตถุใน Java อินสแตนซ์ของคลาสไม่

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

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

สิ่งที่คุณอธิบายคือ OO

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

การวางแนววัตถุนั้นเกี่ยวกับการส่งข้อความ ( การจัดส่งไดนามิก ) คำว่า "Object Oriented" จัดทำโดย Dr. Alan Kay ผู้ออกแบบหลักของ Smalltalk และเขานิยามดังนี้:

OOP สำหรับฉันหมายถึงเพียงการส่งข้อความการเก็บรักษาในท้องถิ่นและการป้องกันและการซ่อนกระบวนการของรัฐและการผูกมัดปลายสุดของทุกสิ่ง

มาทำลายมันกันเถอะ:

  • ส่งข้อความ ("การกระจายวิธีการเสมือน" หากคุณไม่คุ้นเคยกับ Smalltalk)
  • กระบวนการของรัฐควรจะเป็น
    • เก็บไว้ในเครื่อง
    • มีการป้องกัน
    • ซ่อนเร้น
  • สุดขีดผูกพันทุกสิ่ง

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

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

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

แนวคิดหลักคือ "การส่งข้อความ" - นั่นคือสิ่งที่ kernal ของ Smalltalk / Squeak เป็นเรื่องเกี่ยวกับ (และเป็นสิ่งที่ไม่เคยเสร็จสมบูรณ์ในระยะ Xerox PARC ของเรา) ภาษาญี่ปุ่นมีคำขนาดเล็ก - มา - สำหรับ "สิ่งที่อยู่ระหว่าง" - อาจเทียบเท่าภาษาอังกฤษที่ใกล้ที่สุดคือ "คั่นระหว่างหน้า" กุญแจสำคัญในการทำให้ระบบที่ยอดเยี่ยมและเติบโตได้นั้นมีมากขึ้นในการออกแบบว่าโมดูลสื่อสารได้อย่างไรมากกว่าคุณสมบัติและพฤติกรรมภายในของมัน คิดถึงอินเทอร์เน็ต - เพื่อการมีชีวิตอยู่ (ก) ต้องอนุญาตให้มีความคิดและการรับรู้ที่แตกต่างหลากหลายซึ่งอยู่นอกเหนือมาตรฐานเดียวและ (b) เพื่อให้การทำงานร่วมกันอย่างปลอดภัยระหว่างความคิดเหล่านี้มีระดับแตกต่างกัน

(แน่นอนวันนี้ผู้คนส่วนใหญ่ไม่ได้สนใจวัตถุ แต่เรียนซึ่งผิดยิ่งกว่า)

การส่งข้อความเป็นพื้นฐานของ OO ทั้งในฐานะคำอุปมาและเป็นกลไก

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

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

ดังนั้นมีสองวิธีในการดูคำจำกัดความของ Alan Kay: หากคุณมองมันด้วยตนเองคุณอาจสังเกตว่าการส่งข้อความนั้นเป็นการเรียกขั้นตอนที่ล่าช้าและการผูกปลายหมายถึงการห่อหุ้มดังนั้นเราจึงสามารถสรุปได้ว่า # 1 และ # 2 ซ้ำซ้อนจริง ๆ และ OO นั้นเกี่ยวกับการผูกสาย

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

ประเด็นที่คล้ายกันนี้จัดทำขึ้นในการทำความเข้าใจเกี่ยวกับข้อมูลที่เป็นนามธรรม RevisitedโดยWilliam R. Cookและข้อเสนอของเขาสำหรับประยุกต์คำจำกัดความที่ทันสมัยของ "Object" และ "Object Oriented" :

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

ใน Smalltalk-72 ไม่มีแม้แต่วัตถุใด ๆ ! มีเฉพาะสตรีมข้อความที่แยกวิเคราะห์เขียนใหม่และเปลี่ยนเส้นทางใหม่ วิธีมาก่อน (วิธีมาตรฐานในการแยกวิเคราะห์และเปลี่ยนเส้นทางสตรีมข้อความ) มาวัตถุในภายหลัง (การจัดกลุ่มของวิธีการที่ใช้ร่วมกันบางรัฐส่วนตัว) การสืบทอดมามากในภายหลังและชั้นเรียนได้รับการแนะนำเป็นเพียงวิธีการในการสนับสนุนการสืบทอด หากกลุ่มวิจัยของเคย์รู้เรื่องต้นแบบแล้วพวกเขาอาจจะไม่เคยเข้าชั้นเรียนตั้งแต่แรก

เบนจามินเพียร์ซในประเภทและการเขียนโปรแกรมภาษาระบุว่าการกำหนดคุณสมบัติของวัตถุปฐมนิเทศคือเปิด Recursion

ดังนั้นตาม Alan Kay, OO คือทั้งหมดที่เกี่ยวกับการส่งข้อความ ตามที่ William Cook, OO เป็นข้อมูลเกี่ยวกับวิธีการจัดส่งแบบไดนามิก (ซึ่งเป็นสิ่งเดียวกันจริงๆ) ตามข้อมูลของเบนจามินเพียร์ซ OO เป็นข้อมูลเกี่ยวกับ Open Recursion ซึ่งโดยทั่วไปหมายความว่าการอ้างอิงตนเองนั้นได้รับการแก้ไขแบบไดนามิก (หรืออย่างน้อยนั่นก็เป็นวิธีคิด) หรือพูดอีกอย่างคือการส่งข้อความ

อย่างที่คุณเห็นคนที่เป็นคนบัญญัติศัพท์คำว่า "OO" นั้นมีมุมมองทางอภิปรัชญาค่อนข้างสูงบนวัตถุ Cook มีมุมมองเชิงปฏิบัติมากกว่าและเพียร์ซมีมุมมองทางคณิตศาสตร์ที่เข้มงวดมาก แต่สิ่งที่สำคัญคือนักปรัชญานักปฏิบัตินิยมและนักทฤษฎีล้วนเห็นด้วย! การส่งข้อความเป็นเสาหลักเดียวของ OO ระยะเวลา

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


16
+100 - เราโยนความผิดโดยเนื้อแท้กับสิ่งต่าง ๆ เพราะมันถูกใช้อย่างไม่เหมาะสม
JeffO

55
ขออภัย แต่มันผิดอย่างไม่น่าเชื่อ อลันเคย์อาจเกิดคำศัพท์ขึ้นมา แต่หลักการอยู่ข้างหน้าสมอลล์ทอล์ค การเขียนโปรแกรมเชิงวัตถุนั้นมาจาก Simula และรูปแบบ OO ของมันไม่เกี่ยวข้องกับ "ข้อความ" ภาษา OO ทุกภาษาที่ประสบความสำเร็จนั้นดำเนินไปตามหลักการพื้นฐานที่กำหนดไว้ใน Simula ซึ่งเป็นภาษาเดียวกับที่เราเห็นใน Java และ OO สไตล์ Smalltalk นั้นล้มเหลวใน "ตลาดของความคิด" ทุกครั้งที่มีการนำเสนอใหม่ เพราะมันใช้งานได้ไม่ดีเลย ชื่อเป็นสิ่งเดียวที่เคย์มีความหมายอย่างแท้จริง
Mason Wheeler

23
@ steakexchange ไม่ "สาระสำคัญของ OO" สิ่งที่ทำให้มันโดดเด่นอย่างแท้จริงคือวัตถุที่มีวิธีการเสมือน มีเหตุผลที่ไม่มีใครใช้ Smalltalk: ระบบส่งข้อความทำงานได้ไม่ดีในเครื่องคอมพิวเตอร์ส่วนบุคคล ทุกครั้งที่นักออกแบบภาษาที่มีเจตนาดี แต่ไร้เดียงสาพยายามที่จะนำหลักการ Smalltalk กลับมาใช้ใหม่มันจะล้มเหลว (ตัวอย่างล่าสุดคือ Objective-C ซึ่งไม่มีใครเคยใช้ถ้าสตีฟจ็อบส์ไม่ได้ผลักมันลงไปในชุมชน iOS ทั้งคอมันไม่เคยพบว่ามีแรงฉุดนอกระบบนิเวศของ Apple และมีเหตุผลสำหรับสิ่งนั้น )
Mason Wheeler

28
@MasonWheeler คุณช่วยอธิบายความคิดเห็นของคุณได้อย่างละเอียดเพราะคุณมีมุมมองที่ตรงกันข้ามกับสิ่งที่ Jorg พูด?
steakexchange

20
นอกจากนี้ยังควรทราบด้วยว่าแนวคิดของภาษาเชิงวัตถุมีการพัฒนาไปมาก แนวคิดเกี่ยวกับบรรพบุรุษเหล่านั้นอาจไม่เป็นความจริงในทุกวันนี้ด้วยภาษาจำนวนมากที่ใช้โมเดลเก่า ๆ และโอบกอดกระบวนทัศน์แบบหลากหลาย ตัวอย่างเช่นดู C # - ภาษานั้นผสมกันเกือบทุกอย่างภายใต้ดวงอาทิตย์ในขณะที่ในขณะที่ส่วนใหญ่เรียกว่าภาษา OO จริงๆแล้วมันเป็นการผสมผสานของกระบวนทัศน์ที่แตกต่างกัน ที่ช่วยให้มันเป็นเครื่องมือที่แสดงออกอย่างแท้จริงสำหรับนักพัฒนาทั่ว นอกจากนี้ OO แบบคลาสเป็นหนึ่งในรสชาติที่ถูกต้องของการเขียนโปรแกรม OO
T. Sar

66

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

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

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

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

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

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

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

โปรแกรมเมอร์ที่มีทักษะเพียงพอและมีระเบียบวินัยสามารถสร้างระบบที่มีความซับซ้อนสูงใน C หรือการประกอบได้ แต่เราไม่ใช่ Linus Torvalds ทั้งหมด ไม่ควรที่เราจะต้องสร้างซอฟต์แวร์ที่มีประโยชน์

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

ดังนั้นฉันจะเปลี่ยนคำถามของคุณและถามคุณว่าถ้าภาษามีคุณสมบัติที่สะดวกสบายเช่นการห่อหุ้มและ polymorphism ทำไมเราไม่ควรใช้มัน


13
ดังนั้นโดยทั่วไปแล้วมันเป็นไปได้ที่จะทำ OO ด้วยภาษาขั้นตอน แต่นั่นคือการทำสิ่งต่าง ๆ ด้วยตนเองในขณะที่ใช้ภาษา OO ที่เป็นมาตรฐานโดยอัตโนมัติและทำให้ง่ายขึ้น
steakexchange

6
@ steakexchange สวยมากว่า
ทิม B

3
@ steakexchange ตัวอย่างประวัติศาสตร์ที่ดีของสิ่งนี้คือโมเดลวัตถุสำหรับ X Windows ในตอนกลางวัน มันเขียนใน C แต่ขึ้นอยู่กับระบบเชิงวัตถุ ดังนั้นคุณต้องปฏิบัติตามอนุสัญญาบางอย่างเพื่อเชื่อมต่อกับมันดังนั้นชั้นเรียนของคุณจะเล่นได้ดีกับคนอื่น ๆ
Ukko

7
@nocomprende แน่นอน แต่อาจทำให้คอมพิวเตอร์ไม่สามารถบูตได้โดยการเขียนข้อมูลดิบแทนการใช้ระบบไฟล์และจะยากที่จะแก้ไขปัญหาในระบบวัตถุแบบ ad-hoc ที่สร้างโดยมือใหม่ การห่อหุ้มเมื่อทำอย่างถูกต้องจะป้องกันไม่ให้เราเข้าไปยุ่งกับสิ่งที่เราไม่ควรตั้งใจหรือไม่ตั้งใจ
Clement Cherlin

3
เป็นเรื่องที่น่าสนใจสำหรับฉันที่ตัวอย่างที่คุณมอบให้กับแอปพลิเคชันที่จะได้รับประโยชน์จาก OO มักไม่ได้เขียนด้วยภาษา OO ปาเก็ตตี้อายุ 40 ปีน่าจะเขียนใน C, COBOL, FORTRAN หรือ REXX เครื่องมือจัดการดิสเพลย์น่าจะเขียนด้วยภาษา C (แม้ว่าจะมีอนุสัญญา OO-ish) และระบบมัลติเธรดแบบกระจายที่ประสบความสำเร็จจำนวนมากถูกเขียนใน Erlang, Go หรือ C
James_pic

22

สิ่งที่คุณกำลังอธิบายไม่ใช่ OOP มันเป็นนามธรรม สิ่งที่เป็นนามธรรมนั้นมีอยู่ในการออกแบบที่ทันสมัยทุกรุ่นแม้กระทั่งที่ไม่ใช่ OOP และ OOP ก็เป็นนามธรรมที่เฉพาะเจาะจง

อย่างแรกมันก็น่าสังเกตว่าไม่มีคำจำกัดความของ OOP ดังนั้นอาจมีคนที่ไม่เห็นด้วยกับสิ่งที่ฉันเป็นลักษณะ OOP

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

อย่างไรก็ตามนี่คือวิธีการบางอย่างที่ OOP เหมาะสมยิ่งกว่าที่คุณพูด:

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

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

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

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

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


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

@DW ฉันได้พยายามอธิบายสิ่งนี้โดยบอกว่ามันไม่ซ้ำกับ OOP แต่มันเป็นความแตกต่างระหว่างการห่อหุ้มและนามธรรม ขอบคุณสำหรับความคิดเห็น!
jmite

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

การสืบทอดเป็นคุณสมบัติทั่วไป แต่ภาษา OO สำคัญหลายภาษาขาดอยู่
Bradd Szonye

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

11

เราต้องการภาษา OO เพื่อจัดการความซับซ้อนของซอฟต์แวร์หรือไม่?

ขึ้นอยู่กับความหมายของคำว่า "ต้องการ"

หาก "ต้องการ" หมายถึงต้องการเราก็ไม่จำเป็นต้องใช้

หาก "ต้องการ" หมายถึง "ให้ผลประโยชน์ที่รัดกุม" จากนั้นฉันจะบอกว่า "ใช่" เราต้องการ

ภาพใหญ่

ภาษา OO ผูกฟังก์ชันการทำงานกับข้อมูล

คุณสามารถหลีกเลี่ยงการผูกและเขียนฟังก์ชั่นที่ผ่านรอบค่าข้อมูล

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

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

คุณสมบัติตามคุณสมบัติ

คุณสมบัติของ OOP:

  • Inheritanceอนุญาตให้ใช้โค้ด (มิกซ์อิน) และแนวคิด (Abstract Base Classes / interfaces) นำมาใช้ใหม่ - แต่คุณสามารถรับสิ่งนี้ได้โดยการทำซ้ำฟังก์ชันและตัวแปรในขอบเขตย่อย
  • การห่อหุ้มช่วยให้สามารถซ่อนข้อมูลเพื่อให้เราสามารถทำงานในระดับที่สูงขึ้นของนามธรรม - แต่คุณสามารถทำได้ด้วยไฟล์ส่วนหัวฟังก์ชั่นและโมดูล
  • polymorphismช่วยให้เราสามารถใช้การขัดแย้งของประเภทที่แตกต่างกันตราบใดที่ข้อโต้แย้งผู้สนับสนุนอินเตอร์เฟซเดียวกัน - แต่เราสามารถทำกับฟังก์ชั่นเช่นกัน

อย่างไรก็ตามไม่มีสิ่งเหล่านี้เกิดขึ้นได้อย่างง่ายดายเหมือนกับภาษาเชิงวัตถุที่มีการสนับสนุนชั้นหนึ่งของคุณสมบัติเหล่านั้น

อ้างอิง

มีนักวิจารณ์ OOPมากมาย

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

ข้อสรุป

เราไม่ "ต้องการ" OOP แต่ในบางกรณีผู้ใช้ต้องการ OOP

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


10

ฉันจะพยายามสรุป

หลักการหลักของ OO คือการรวมกันของข้อมูลและพฤติกรรมในหน่วยองค์กรเดียว (วัตถุ)

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

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

ดังนั้นใช่ OO เป็นเรื่องใหญ่ และไม่ใช่มันไม่ใช่แค่ของโบราณที่มีชื่อแฟนซี

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


8

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

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

ฉันคิดว่าหลักการทั้งหมดที่ใช้ในการจัดการความซับซ้อนนั้นสามารถเกิดขึ้นได้ด้วยภาษาโปรแกรมขั้นตอน

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


7

คำตอบอื่น ๆ ที่ไม่ได้กล่าวถึง: รัฐ

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

สิ่งที่ฉันคิดว่าเรากำลังพูดถึงคือความซับซ้อนที่เกี่ยวข้องกับรัฐ

มีสองความคิดหลักที่อยู่เบื้องหลังมีการห่อหุ้ม หนึ่งในนั้นคือการซ่อนรายละเอียดการใช้งานซึ่งค่อนข้างครอบคลุมในคำตอบอื่น ๆ แต่อีกสิ่งหนึ่งซ่อนสถานะของเวลาทำงานไว้ เราไม่เข้าไปยุ่งกับข้อมูลภายในของวัตถุ เราส่งข้อความ (หรือวิธีการโทรหากคุณต้องการรายละเอียดการใช้งานมากกว่าแนวคิดตามJörg Mittag ชี้ให้เห็น) ทำไม?

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

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

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

ในทางกลับกัน OO เสนอเครื่องมือในการจัดการกับสถานะการจัดการ (แทนที่จะเป็นเครื่องมือสำหรับหลีกเลี่ยง) นอกจากเครื่องมือระดับภาษาเช่นตัวดัดแปลงการเข้าถึง (ป้องกัน / สาธารณะ / ส่วนตัว), ตัวรับและตัวตั้งค่า ฯลฯ ยังมีข้อตกลงที่เกี่ยวข้องอีกหลายอย่างเช่นกฎแห่ง Demeter ซึ่งแนะนำให้เข้าถึงวัตถุผ่านข้อมูลอื่น ๆ .

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


5

เราต้องการภาษา OO เพื่อจัดการความซับซ้อนของซอฟต์แวร์หรือไม่?

ไม่ได้ แต่พวกเขาสามารถช่วยได้ในหลาย ๆ สถานการณ์

ฉันได้ใช้ภาษา OO เป็นหลักมานานหลายทศวรรษแล้ว แต่ส่วนใหญ่ของรหัสของฉันเป็นขั้นตอนก่อนสไตล์ OO อย่างเคร่งครัด อย่างไรก็ตามสำหรับสิ่งใดก็ตามที่เกี่ยวข้องกับ GUI ฉันใช้ไลบรารี OO อันกว้างใหญ่ของภาษาสำหรับวิธีการและวัตถุในตัวเพราะมันทำให้รหัสของฉันง่ายขึ้นอย่างมาก

ตัวอย่างเช่นแอปพลิเคชัน Windows ที่ใช้ Windows API ระดับต่ำดั้งเดิมเพื่อแสดงฟอร์มปุ่มและฟิลด์แก้ไขต้องใช้รหัสจำนวนมากในขณะที่ใช้ไลบรารีของวัตถุที่มาพร้อมกับ Visual Basic หรือ C # หรือ Delphi แทน โปรแกรมเล็กและไม่สำคัญ ดังนั้นรหัส OO ของฉันมักจะค่อนข้างเล็กและสำหรับ GUI ในขณะที่รหัสของฉันที่วัตถุเหล่านั้นเรียกใช้นั้นใหญ่กว่ามากและมักจะไม่เกี่ยวข้องกับการเป็น OO (แม้ว่ามันจะแตกต่างกันไปขึ้นอยู่กับปัญหาที่ฉันพยายามแก้ไข)

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

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


3

ในฐานะที่เป็นคนที่มีส่วนร่วมในโครงการขนาดใหญ่มากที่เขียนด้วยภาษา C ฉันสามารถพูดได้อย่างแน่นอนว่าคำตอบนั้นชัดเจน "ไม่"

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

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

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

พิจารณาโครงการโอเพนซอร์ซที่ซับซ้อนที่สุด คือเคอร์เนล Linux มันเขียนทั้งหมดในภาษา C มันทำส่วนใหญ่โดยใช้เครื่องมือมาตรฐาน modularity ระดับการรวบรวมรวมถึงองค์ประกอบและจากนั้นบางครั้งเมื่อใดก็ตามที่จำเป็นต้องใช้แบบแยกส่วน runtime, ตัวชี้ฟังก์ชั่นจะใช้ในการกำหนดและใช้อินเตอร์เฟซ

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

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

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


1
"[... ] ข้อสรุปคือภาษาเชิงวัตถุน่าจะมีประโยชน์สำหรับโปรแกรมเมอร์มือใหม่ที่ล้มเหลวในการทำความเข้าใจวิธีการนำแนวคิดมาใช้จริง" น่าสนใจ คุณมีภาษาอะไรในใจ? คุณมีตัวอย่างของโครงการโอเพนซอร์ซที่เขียนด้วยภาษาเหล่านี้ซึ่งล้มเหลวหรือไม่ล้มเหลว?
Vincent Savard

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

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

1
เพื่อชี้แจงความคิดเห็นล่าสุดของฉันจุดของฉันคือว่าปัจจัยหลักที่แตกต่าง b ระหว่าง OOP (ไม่จำเป็นต้องมีภาษา OO เฉพาะ) และวิธีอื่น ๆ คือใน OOP เรากำหนดอินเตอร์เฟสที่ทำงานนามธรรมบนข้อมูลโดยไม่จำเป็นต้องรู้รูปแบบของข้อมูลโดย ผูกการดำเนินการของอินเทอร์เฟซกับข้อมูลตัวเอง นั่นคือสิ่งที่ OOP วิธีการใช้งานไม่เกี่ยวข้องไม่ว่าจะเป็นคลาสสไตล์ Java วัตถุ JavaScript (แผนที่ชื่อเพื่อแอตทริบิวต์ซึ่งอาจเป็นข้อมูลหรือรหัส) หรือโครงสร้างที่มีตัวชี้ฟังก์ชั่นและโมฆะ * สำหรับข้อมูล
Jules

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

2

เหตุผลในการแนะนำกระบวนทัศน์การเขียนโปรแกรมรวมถึงวิธีการเชิงวัตถุคือการทำให้โปรแกรมที่ซับซ้อนและมีประสิทธิภาพมากขึ้นง่ายขึ้น ในนิตยสาร Byte ฉบับเดือนสิงหาคม 1981 Daniel Ingallsหนึ่งในผู้สร้างหลักของ Smalltalk ได้นิยาม "object oriented" ซึ่งเกี่ยวข้องกับความสามารถดังต่อไปนี้:

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

นี่เป็นหลักการที่อิงกัลระบุว่าเป็นข้อพิจารณาในการออกแบบการขับขี่สำหรับ SmallTalk-80 ที่พัฒนาโดย Xerox Parc Research ในบทความในนิตยสารดังกล่าวคุณสามารถอ่านคำอธิบายโดยละเอียดของแต่ละหลักการเหล่านี้และวิธีที่พวกเขามีส่วนร่วมในกระบวนทัศน์เชิงวัตถุตาม Ingalls

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

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


ฉันคิดว่าจะใช้กฎเดียวกันนี้ในกรณีของ Domain Specific Languages ข้อดีและข้อเสียที่เหมือนกัน ... ความแตกต่างอย่างหนึ่งคือ DSL สามารถทำได้ง่ายพอสำหรับผู้ใช้ปลายทางเนื่องจาก 'ภาษา' สอดคล้องกับความเข้าใจในพื้นที่ปัญหาและไม่มีสิ่งใดรวมอยู่

0

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

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

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


0

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

จุดมุ่งหมายคือ - จัดการซอฟท์แวซับซ้อน เป้าหมายไม่ใช่ "ใช้ภาษา OO"

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


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


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

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

ดังนั้นคุณสามารถเขียนโค้ดที่เข้ารหัสและ encapsulated ได้ดีเพราะทั้งสองเป็นแนวคิดที่แตกต่างกัน

Encapsulation ช่วยในการจัดการความซับซ้อนโดยอาศัยอยู่ใกล้กับความเป็นจริง

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


0

สิ่งหนึ่งที่ต้องจดจำคือ:
OOP ไม่ได้เกี่ยวกับคุณสมบัติทางภาษา มันเป็นเรื่องเกี่ยวกับวิธีการที่คุณโครงสร้างรหัสของคุณ

OOP เป็นวิธีคิดและการออกแบบสถาปัตยกรรมรหัสของคุณและสามารถทำได้ในภาษาใดก็ได้ โดยเฉพาะอย่างยิ่งสิ่งเหล่านี้รวมถึงภาษาที่ไม่ใช้ภาษา OO ระดับต่ำซึ่งเรียกว่า assembler และ C คุณสามารถทำการเขียนโปรแกรมเชิงวัตถุในแอสเซมเบลอร์และเคอร์เนล Linux ซึ่งเขียนด้วยภาษา C ค่อนข้างเชิงวัตถุในหลาย ๆ ด้าน .

ที่กล่าวว่าคุณสมบัติ OO ในภาษาที่ช่วยลดปริมาณของรหัสสำเร็จรูปที่คุณจะต้องเขียนเพื่อให้บรรลุผลที่ต้องการ ที่ที่คุณต้องการกำหนดตารางฟังก์ชันเสมือนอย่างชัดเจนและเติมด้วยตัวชี้ฟังก์ชันที่เหมาะสมใน C คุณเพียงแค่ไม่ทำอะไรใน Java และเสร็จแล้ว ภาษา OO เพียงลบสิ่งที่เปิดใช้งาน cruft ออกจากซอร์สโค้ดซ่อนอยู่ด้านหลัง abstractions ระดับภาษาที่ดี (เช่นคลาส, เมธอด, สมาชิก, คลาสพื้นฐาน, การโทรคอนสตรัคเตอร์ / destructor โดยปริยายเป็นต้น)

ดังนั้นไม่เราไม่ต้องการภาษา OO ในการทำ OOP เป็นเพียงว่า OOP นั้นง่ายกว่ามากในการใช้ภาษา OO ที่เหมาะสม


-1

การเขียนโปรแกรมเชิงวัตถุเป็นมากกว่าโมดูล + การห่อหุ้ม อย่างที่คุณพูดมันเป็นไปได้ที่จะใช้โมดูล + การห่อหุ้มในภาษาที่ไม่ใช่เชิงวัตถุ (ขั้นตอน) OOP เกี่ยวข้องกับมากกว่านั้น: มันเกี่ยวข้องกับวัตถุและวิธีการ ดังนั้นไม่ว่าจะไม่จับภาพ OOP ดูเช่นhttps://en.wikipedia.org/wiki/Object-oriented_programmingหรือแนะนำตำราเรียนที่ดีเกี่ยวกับ OOP


ขอบคุณสำหรับคำตอบ คุณแนะนำได้ไหม
steakexchange

-2

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

ลองจินตนาการถึงระบบ 100 คลาสแต่ละอันมีการดำเนินการประมาณ 20 ครั้งที่สามารถทำได้ นั่นคือ 2,000 ฟังก์ชัน อย่างไรก็ตามมีเพียง 500 รายการที่ดำเนินการอย่างสมบูรณ์เช่น 'บันทึก' และ 'ลบ' ในขณะที่ 1500 เป็นฟังก์ชันภายในที่มีการบำรุงรักษาเล็กน้อยหรือมีบทบาทด้านอรรถประโยชน์ พิจารณา;

// intentionally in a non-specific language!

setName(person, name) {
    nameParts = splitPersonName(name);
    person.firstName = nameParts[0];
    person.lastName = nameParts[1];
    person.modified = true;
}

splitPersonName(name) {
    var result = [];
    result.add(name.substring(0, name.indexOf(" ")));
    result.add(name.substring(name.indexOf(" ") + 1));
    return result;
}

ดังนั้นSetNameฟังก์ชั่นที่คนควรทำกับคน แต่SplitPersonNameเป็นฟังก์ชั่นยูทิลิตี้ที่ใช้โดยบุคคล

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

นั่นคือสิ่งที่publicและprivateทำ;

public class Person {
    public void setName(...) {...}
    private string[] splitPersonName(...) { ...}
}

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

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

3
@steakexchange โปรดทราบว่า OOP ได้รับการพัฒนาในช่วงเวลาที่ภาษาขั้นตอนจำนวนมากไม่มีโมดูลเช่นนั้น บางคนอาจไม่เรียกขั้นตอนภาษาเหล่านี้ แน่นอนว่าไม่มีสิ่งใดที่บอกว่าภาษาเชิงปฏิบัติต้องไม่เป็น OO หรือในทางกลับกัน ระวังฉลาก - มันอาจทำให้คุณเข้าใจผิดได้ง่าย หากภาษาเชิงปฏิบัติของคุณสนับสนุนโมดูลที่มีเขตข้อมูลภาครัฐและเอกชนดีสำหรับคุณ :) ความแตกต่างที่สำคัญระหว่าง "ขั้นตอนแบบดั้งเดิม" และ "OOP" คือการส่งสายมีความยืดหยุ่นมากขึ้นใน OOP - แน่นอนใน OOP ที่เข้มงวดคุณไม่เคยรู้รหัสที่คุณโทร
Luaan

2
@steakexchange ในภาษาตระกูล ML โมดูลใช้งานได้ดีและเมื่อใช้ร่วมกับ lambdas พวกมันให้พลังทั้งหมดของภาษา OO ใด ๆ (ท้ายที่สุดแล้วฟังก์ชั่นคืออินเทอร์เฟซด้วยวิธีการเดียว - ไม่ใช่ว่าเกือบจะเป็นสิ่งที่แนะนำโดย "รหัสที่ดี" พวกใน OO?: P) ด้วยเหตุผลต่าง ๆ พวกเขายังคงใช้น้อยกว่าภาษาขั้นตอนเพิ่มเติมเช่น C ++ หรือ Java แต่มีการอุทธรณ์และหลายคนพยายามให้ความรู้แก่ผู้คนเกี่ยวกับวิธีที่พวกเขาสามารถทำให้ชีวิตของพวกเขาง่ายขึ้น (ประสบความสำเร็จน้อยลง)
Luaan

C ได้อย่างมีประสิทธิภาพสิ่งเหล่านี้ มันมีโมดูล (ไฟล์. c) พร้อมอินเทอร์เฟซ (ไฟล์. h) และสามารถมีวิธีสาธารณะ (extern) และไม่ใช่แบบสาธารณะ (ภายนอก) (ฟังก์ชัน) คุณสามารถมีความหลากหลายของคนจนด้วยอาร์เรย์ของพอยน์เตอร์ฟังก์ชั่นฉันไม่ได้บอกว่า OO นั้นง่ายใน C (หรือบางทีมีสติ) แต่การห่อหุ้มนั้นค่อนข้างง่าย
Nick Keighley
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.