ทำไม“ การมีเพศสัมพันธ์อย่างแน่นหนาระหว่างฟังก์ชั่นและข้อมูล” ไม่ดี?


38

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

[A] ข้อเสียของการเขียนโปรแกรมเชิงวัตถุคือการมีเพศสัมพันธ์อย่างแน่นหนาระหว่างฟังก์ชั่นและข้อมูล

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

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

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

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

ดังนั้น Clojure มีเนมสเปซ การผสานฟังก์ชันกับคลาสใน OOP แตกต่างจากการผสานฟังก์ชันในเนมสเปซใน Clojure ได้อย่างไรและทำไมมันจึงไม่ดี โปรดจำไว้ว่าฟังก์ชั่นในชั้นเรียนไม่จำเป็นต้องทำงานกับสมาชิกของคลาสนั้นเสมอไป ดูที่ java.lang.StringBuilder - ทำงานกับประเภทการอ้างอิงใด ๆ หรือผ่าน auto-Boxing ทุกประเภท

อ้างอิง PS อ้างหนังสือเล่มนี้ที่ผมยังไม่ได้อ่าน: การเขียนโปรแกรม Multiparadigm ใน Leda: ทิโมธี Budd 1995


20
ฉันเชื่อว่าผู้เขียนไม่เข้าใจ OOP อย่างถูกต้องและต้องการเหตุผลอีกหนึ่งข้อในการบอกว่า Java ไม่ดีและ Clojure นั้นดี / พูดจาโผงผาง
สุข

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

4
@Euphoric ผมเชื่อว่าผู้เขียนไม่เข้าใจ แต่ชุมชน Clojure ที่ดูเหมือนว่าจะชอบที่จะทำให้เป็นคนที่ฟางของ OOP และการเผาไหม้เป็นรูปจำลองสำหรับทุกความชั่วร้ายของการเขียนโปรแกรมก่อนที่เราจะมีการเก็บขยะที่ดีมากของหน่วยความจำหน่วยประมวลผลที่รวดเร็วและ พื้นที่ดิสก์จำนวนมาก ฉันหวังว่าพวกเขาจะเลิกเต้นกับ OOP และกำหนดเป้าหมายที่แท้จริงเช่นสถาปัตยกรรม Von Neuman
GlenPeterson

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

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

คำตอบ:


34

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

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

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

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


13

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

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

นั่นคือข้อเสียของ OO - มันส่งเสริมความชั่วร้ายชนิดนี้การมีเพศสัมพันธ์ของข้อมูลในการทำงานผ่านการสร้างมาตรฐานการปิด (ซึ่งเป็นทฤษฎีการเขียนโปรแกรมหน้าต่างแตก )

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


8
ใบเสนอราคาประจำวัน: "ความชั่วร้ายบางอย่างมักจำเป็นต่อการทำงานให้เสร็จ"
GlenPeterson

5
คุณไม่ได้อธิบายอย่างแท้จริงว่าทำไมสิ่งที่คุณเรียกว่าความชั่วร้ายนั้นเป็นความชั่วร้าย คุณแค่เรียกพวกเขาว่าชั่วร้าย อธิบายว่าทำไมพวกเขาถึงชั่วร้ายและคุณอาจมีคำตอบสำหรับคำถามของสุภาพบุรุษ
Robert Harvey

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

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

1
@itsbruce พวกมันไม่จำเป็นเลย ตัวแปรที่จะเป็น "ปิด" แทนที่จะเป็นตัวแปรคลาสที่ส่งผ่านเข้าไปในวัตถุ
Izkata

7

มันเกี่ยวกับการมีเพศสัมพันธ์ประเภท :

ฟังก์ชั่นที่อยู่ภายในวัตถุเพื่อทำงานกับวัตถุนั้นไม่สามารถใช้กับวัตถุประเภทอื่นได้

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

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


3
นั่นคือจุดรวมของอินเตอร์เฟสทั้งหมดใช่ไหม เพื่อให้สิ่งที่อนุญาตให้พิมพ์ B และ C มีลักษณะเหมือนกันกับฟังก์ชั่นของคุณดังนั้นมันสามารถทำงานได้มากกว่าหนึ่งประเภท?
Random832

2
@ Random832 อย่างแน่นอน แต่ทำไมฝังฟังก์ชั่นภายในของชนิดข้อมูลถ้าไม่ทำงานกับชนิดข้อมูลนั้น? คำตอบ: มันเป็นเหตุผลเดียวที่จะฝังฟังก์ชั่นในรูปแบบข้อมูล คุณไม่สามารถเขียนอะไรได้นอกจากคลาสแบบสแตติกและทำให้ทุกฟังก์ชั่นของคุณไม่สนใจเกี่ยวกับประเภทข้อมูลที่ถูกห่อหุ้มไว้เพื่อให้แยกออกจากประเภทการเป็นเจ้าของของพวกเขาได้อย่างสมบูรณ์ ฟังก์ชั่นการใช้งานพูดว่า: อย่ากังวลเขียนฟังก์ชั่นของคุณเพื่อใช้งานอินเทอร์เฟซแปลก ๆ จากนั้นก็ไม่มีเหตุผลที่จะแค็ปซูลกับข้อมูลของคุณ
จิมมี่ฮอฟฟา

คุณยังต้องใช้อินเทอร์เฟซ
Random832

2
@ Random832 อินเตอร์เฟสเป็นชนิดข้อมูล พวกเขาไม่ต้องการฟังก์ชั่นที่ห่อหุ้มในพวกเขา ด้วยฟังก์ชั่นที่ไม่เสียค่าใช้จ่ายอินเทอร์เฟซทั้งหมดจำเป็นต้องเพิ่มขึ้นมาใหม่คือข้อมูลที่พวกเขาทำให้พร้อมใช้งานสำหรับฟังก์ชั่นการทำงาน
จิมมี่ฮอฟฟา

2
@ Random832 เพื่อเชื่อมโยงกับวัตถุในโลกแห่งความเป็นจริงที่พบได้ทั่วไปใน OO ให้นึกถึงส่วนต่อประสานของหนังสือ: นำเสนอข้อมูล (data) นั่นคือทั้งหมด คุณมีฟังก์ชั่นฟรีของ turn-page ที่ทำงานกับประเภทของประเภทที่มีหน้าได้ฟังก์ชั่นนี้ทำงานได้กับหนังสือทุกประเภท, หนังสือพิมพ์, ข่าว, โปสเตอร์เหล่านั้นแกนที่ K-Mart, การ์ดอวยพร, จดหมาย, อะไรก็ตามที่เย็บติดกันใน มุม. หากคุณใช้งานเทิร์นเพจในฐานะสมาชิกของหนังสือคุณจะพลาดทุกสิ่งที่คุณสามารถใช้เทิร์นเพจได้เนื่องจากเป็นฟังก์ชั่นฟรีที่ไม่ผูกมัด มันเพิ่งโยน PartyFoulException บนเบียร์
Jimmy Hoffa

4

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

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


คุณสามารถทำได้อย่างง่ายดายใน Scala ฉันไม่คุ้นเคยกับ Go แต่ AFAIK คุณสามารถทำได้ที่นั่น ในทับทิมมันเป็นเรื่องธรรมดาที่จะเพิ่มวิธีการลงในวัตถุหลังจากข้อเท็จจริงเพื่อให้สอดคล้องกับอินเทอร์เฟซบางอย่าง สิ่งที่คุณอธิบายดูเหมือนจะเป็นระบบพิมพ์ที่ออกแบบมาไม่ดีกว่าสิ่งใดก็ตามที่เกี่ยวข้องกับ OO จากระยะไกล เช่นเดียวกับการทดสอบความคิด: คำตอบของคุณจะแตกต่างอย่างไรเมื่อพูดถึงประเภทข้อมูลนามธรรมแทนที่จะเป็นวัตถุ ฉันไม่เชื่อว่ามันจะสร้างความแตกต่างใด ๆ ซึ่งจะพิสูจน์ว่าข้อโต้แย้งของคุณไม่เกี่ยวข้องกับ OO
Jörg W Mittag

1
@ JörgWMittagฉันคิดว่าคุณหมายถึง Algebraic datatypes และ CodesInChaos แฮสเคลล์ไม่สนับสนุนสิ่งที่คุณแนะนำอย่างชัดเจน มันเรียกว่าอินสแตนซ์ที่ถูกกำพร้าและออกคำเตือนเกี่ยวกับ GHC
jozefg

3
@ JörgWMittagความประทับใจของฉันคือหลายคนที่วิพากษ์วิจารณ์ OOP วิพากษ์วิจารณ์รูปแบบของ OOP ที่ใช้ใน Java และภาษาที่คล้ายกันกับโครงสร้างชั้นแข็งและมุ่งเน้นในวิธีการอินสแตนซ์ ความประทับใจของฉันเกี่ยวกับคำพูดนั้นคือมันวิพากษ์วิจารณ์การมุ่งเน้นไปที่วิธีการอินสแตนซ์และไม่ได้ใช้กับรสชาติอื่น ๆ ของ OOP เช่นเดียวกับที่ golang ใช้
CodesInChaos

2
@CodesInChaos จากนั้นอาจจะอธิบายสิ่งนี้ว่า "static class based OO"
jozefg

@jozefg: ฉันกำลังพูดถึงประเภทข้อมูลนามธรรม ฉันไม่เห็นด้วยซ้ำว่าประเภทข้อมูลพีชคณิตมีความเกี่ยวข้องกับการสนทนานี้จากระยะไกลอย่างไร
Jörg W Mittag

3

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

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

สิ่งนี้หมายความว่าวัตถุหลายประเภทเดียวกันอาจมีข้อมูลที่แตกต่างกัน แม้แต่วัตถุเดียวกันก็อาจมีข้อมูลต่างกันในเวลาต่างกัน (ตัวอย่างเช่นใน Scala, Maps และSets สลับระหว่างอาร์เรย์และ hash trie ขึ้นอยู่กับจำนวนขององค์ประกอบเพราะสำหรับการค้นหาเชิงเส้นในจำนวนที่น้อยมากจะเร็วกว่าการค้นหาแบบลอการิทึมในโครงสร้างการค้นหาเนื่องจากปัจจัยคงที่ขนาดเล็กมาก .)

จากด้านนอกของวัตถุคุณไม่ควรคุณไม่สามารถรู้ถึงการแสดงข้อมูล นั่นคือสิ่งที่ตรงกันข้ามกับคลัปแน่น


ฉันมีคลาสใน OOP ที่สลับโครงสร้างข้อมูลภายในขึ้นอยู่กับสถานการณ์ดังนั้นอินสแตนซ์ของคลาสเหล่านี้สามารถใช้การแทนข้อมูลที่แตกต่างกันมากในเวลาเดียวกัน การซ่อนข้อมูลพื้นฐานและการห่อหุ้มข้อมูลที่ฉันพูด ดังนั้น Map ใน Scala แตกต่างจากการใช้งานอย่างถูกต้อง (การซ่อนข้อมูล wrt และการห่อหุ้ม) แผนที่ในภาษา OOP อย่างไร
Marjan Venema

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

2

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

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


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