ออกแบบในภาษา“ แบบผสม”: การออกแบบเชิงวัตถุหรือการโปรแกรมเชิงฟังก์ชันหรือไม่?


11

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

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

ตอนแรกฉันทำมัน "ตามหน้าที่" เช่นนี้:

producer.foo(item => { updateItemInDb(item); insertLog(item) })
// calls the function passed as argument as an item is processed

แต่ตอนนี้ฉันสงสัยว่าฉันควรใช้วิธีการ "OO" เพิ่มเติม:

interface IItemObserver {
  onNotify(Item)
}
class DBObserver : IItemObserver ...
class LogObserver: IItemObserver ...

producer.addObserver(new DBObserver)
producer.addObserver(new LogObserver)
producer.foo() //calls observer in a loop

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

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


นักแสดงล่ะ?
kiritsuku

ลืมคลาสและสิ่งที่ไร้ประโยชน์ทั้งหมดออกไป คุณควรคิดในแง่ของโมดูลแทน (ดูภาษา SML และ OCaml เพื่อเป็นแรงบันดาลใจ)
SK-logic

@Antoras หากคุณสามารถเปรียบเทียบกับวิธีการขึ้นอยู่กับนักแสดงก็จะมีมากขึ้นแล้วยินดี :)
Lorenzo Dematté

2
@ dema80, OCaml นั้นสมบูรณ์แบบหลายกระบวนทัศน์ โมดูลไม่เกี่ยวข้องกับการเขียนโปรแกรมการทำงานเลย มีระบบโมดูลขั้นสูงใน Ada จำเป็นอย่างหมดจดตัวอย่างเช่น และชื่อเสียงทั้งหมดที่ได้รับจาก OOP ควรไปที่โมดูลจริง ๆ สิ่งที่ดีใน OOP นั้นเป็นเพียงการจำลองรูปแบบการทำงานของโมดูลต่างๆ คุณสามารถลืมคลาสทั้งหมดนั้นและใช้ไวยากรณ์ในการแสดงโมดูลแทนโดยคิดในแง่ของโมดูลไม่ใช่ OOP Btw. นั่นคือสิ่งที่ Microsoft ทำกับ mscorlib ของพวกเขา - ไม่มี OOP มากแค่โมดูลและเนมสเปซ
SK-logic

1
ฉันคิดว่าคำถามที่ดีกว่าคือ "มีความชัดเจนหรือองค์กรที่คุณสูญเสียโดยการทำวิธี FP"
djechlin

คำตอบ:


0

นั่นเป็นตัวอย่างที่ดีของวิธีการที่แตกต่างกันสองวิธีที่มีความคิดในการปฏิบัติงานนอกขอบเขตของความกังวลสำหรับวัตถุที่เรียก

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

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


ฉันคิดว่าคำตอบนี้เข้าใจผิดเล็กน้อย ฟังก์ชั่นโปรแกรมมิงไม่ใช่การตั้งโปรแกรม (เฉพาะที่มี) ฟังก์ชั่น ฟังก์ชั่นการเขียนโปรแกรมใช้ abstractions เช่นกันดังนั้นจึงไม่มีการแบ่งขั้วที่นี่
Doval

"องค์ประกอบหรือการสืบทอดที่คุณจะมีอิสระมากขึ้นในการใช้ซ้ำและขยายพฤติกรรมที่มีอยู่" คุณกำลังพูดเช่นนี้ไม่ใช่หนึ่งในประโยชน์หลักของ FP บริสุทธิ์ modularity, การผสมกันและการใช้ซ้ำเกิดขึ้นตามธรรมชาติเมื่อคุณเขียนโค้ดตามหน้าที่นี่ไม่ใช่ "สิ่ง OOP"
sara

@ FilipDupanovićฉันหมายถึงการใช้ซ้ำและขยายรหัสที่มีอยู่ ฟังก์ชั่นที่บริสุทธิ์อาจเป็นสิ่งที่คอมโพสิตที่สุดในการเขียนโปรแกรมทั้งหมด คุณเขียนราวกับว่าคุณไม่สามารถจัดการความซับซ้อนในสภาพแวดล้อมการทำงานที่บริสุทธิ์ การจัดการความซับซ้อนโดยการเขียนชิ้นส่วนที่เรียบง่ายเป็นส่วนใหญ่ แต่ยังคงง่ายและชิ้นส่วนทึบแสงเป็นแกนกลางทั้งหมดของ FP และหลายคนอาจแย้งว่ามันดีกว่า OOP ฉันไม่เห็นด้วยกับการแบ่งขั้วระหว่าง "liners หนึ่งที่ใช้งานได้ซึ่งไม่ได้ปรับขนาด OOP ที่เป็นของแข็ง VS ที่ลดปัญหา" คุณหยิบยก
sara

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

5

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

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


ฉันเห็นด้วยและมีความรู้สึกเดียวกัน
Lorenzo Dematté

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

5

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

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


+1 สำหรับ (IMO) คำตอบที่ดี นอกจากนี้ขอบคุณสำหรับลิงค์ไปยังกระดาษ: ฉันได้อ่านมันเมื่อไม่นานมานี้และจากนั้นก็หายไป ตอนนี้ฉันได้พบมันอีกครั้ง
จอร์โจ

-1

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

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


1
"คุณสามารถใช้ความระมัดระวังอย่างมากในการเขียนโปรแกรมทั้งหมดที่มีวัตถุที่ไม่มีสถานะเลียนแบบ FP" แน่นอนและด้วยวินัยคุณสามารถทำสิ่งเดียวกันในภาษาที่จำเป็นได้เช่นกัน :) โดยทั่วไปแล้วผมไม่คิดว่าที่ patters การออกแบบเป็นสิ่งที่จะทำขึ้นสำหรับข้อ จำกัด แต่พิจารณากรณีของรูปแบบที่ผู้เข้าชม ..
Lorenzo Dematté

นอกจากนี้ฉันไม่ได้เกี่ยวข้องกับรหัส: อย่างไรก็ตามฉันต้องการที่จะเผชิญหน้ากับเพื่อนโปรแกรมเมอร์ในแนวทาง (เพื่อความเข้าใจของฉันนี่คือสิ่งที่ programmers.se มีไว้สำหรับมิฉะนั้นฉันจะโพสต์ Q ของฉันใน SO)
Lorenzo Dematté

ทุกครั้งที่คุณเห็นรูปแบบการทำซ้ำมันไม่มีอะไรนอกจากบ่งบอกถึงข้อ จำกัด ที่รุนแรงของภาษาและกรอบการทำแบบจำลองของคุณ จะไม่มีรูปแบบใด ๆ ในโลกอุดมคติ
SK-logic

@ SK-logic: น่าเสียดายที่โลกไม่เหมาะและโลกแห่งความจริงมีรูปแบบ ซึ่งเป็นสาเหตุที่ภาษา OO มีการสืบทอดเพื่อใช้รหัสที่ยกเลิกได้โดยไม่ต้องเขียนใหม่ทั้งหมดอีกครั้งวัตถุโลกที่แท้จริงมีสถานะนั่นคือสาเหตุที่มีรูปแบบของรัฐ
DPD

1
@ SK-logic: ฉันรู้ดีว่าบางภาษาสามารถตั้งโปรแกรมได้และบางคนก็ยอมให้มีการบังคับเอฟเฟกต์จากระบบพิมพ์ด้วย ประเด็นของฉันคือว่า "OOP" "pattern" เป็นคำที่เข้าใจผิดอย่างน่าเศร้า รูปแบบเป็นสิ่งที่ช่วยให้โผล่มาให้เห็นในรูปแบบคล้ายกัน แต่แตกต่างกันที่ไม่ยอมรับวิธีการแก้ปัญหาเครื่องแบบ บางครั้งคุณสามารถทำให้ quasirepetitions หายไปได้ - วิธีการหลายอย่างทำให้ผู้เยี่ยมชม / ส่งซ้ำซ้อนซ้ำซ้อน นั่นไม่ได้หมายความว่า "รูปแบบทั้งหมดเป็นสัญญาณของการขาด" เพราะนั่นหมายความว่าโลกแห่งความจริงนั้นไม่เพียงพอ รูปแบบเกิดขึ้นในสถาปัตยกรรมไม่ใช่ซอฟต์แวร์
Frank Shearar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.