หลักการและชื่อวิธีการของ OOP


22
class Boxer:

    def punch(self, punching_bag, strength):
        punching_bag.punch(strength)


class PunchingBag:

    def punch(self, strength):
        print "Punching bag punched with strength", strength

boxer = Boxer()
punching_bag = PunchingBag()

boxer.punch(punching_bag, 2)

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

คำตอบ:


23

กฎง่ายๆก็คือชื่อวิธีการที่ควรจะเป็นคำกริยาหรือกริยาที่วัตถุที่คุณเรียกพวกเขาใน ( selfในการประชุม Python มาตรฐานthisในภาษาอื่น ๆ ส่วนใหญ่) กลายเป็นเรื่อง

ตามกฎนี้file.closeเป็นสิ่งที่ผิดเว้นแต่คุณจะไปกับรุ่นจิตที่ไฟล์ปิดตัวเองหรือว่าfileวัตถุไม่ได้เป็นตัวแทนของไฟล์ตัวเอง แต่ค่อนข้างจัดการไฟล์หรือวัตถุ proxy บางประเภท

กระเป๋าเจาะไม่เคยเจาะแม้ว่าpunchingBag.punch()จะผิดทางใดทางหนึ่ง be_punched()ถูกต้องทางเทคนิค แต่น่าเกลียด อาจจะทำงานหรือreceive_punch() handle_punch()อีกวิธีหนึ่งที่นิยมมากใน JavaScript, คือการรักษาโทรวิธีการดังกล่าวเป็นเหตุการณ์ที่เกิดขึ้นและการประชุมที่มีไปกับชื่อเหตุการณ์ที่นำหน้าด้วย 'ใน' เพื่อที่จะเป็นหรือon_punched() on_hit()หรือคุณสามารถนำมาใช้ในการประชุมที่ผ่านมาแสดงให้เห็น participles เสียงเรื่อย ๆ punched()และโดยการประชุมที่ชื่อวิธีการจะเป็นเพียง

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


4
@Artur: ใช่และไม่ใช่ ไฟล์สามารถ (พูดในเชิงแนวคิด) ปิดตัวเองเมื่อถูกถาม อาร์เรย์สามารถจัดเรียงตัวเองได้ แต่ถุงเจาะไม่ต้องชกเอง
tdammers

2
โอเคถ้ากระเป๋าเจาะของเราชนกับผนังด้วยความเร็วบ้ามันเป็นกำแพงที่ต่อยหรือว่าเป็นถุงเจาะที่กระทบกับตัวมันเอง

1
@tdammers: Hitableข้อเสนอแนะของคุณที่จะพูดคุยยังอาจนำไปสู่การอินเตอร์เฟซที่เรียกว่า
Jens Piegsa

2
@Artur: ฉันคิดว่านี่คือที่ OOP สันนิษฐานว่าทุกประโยคมีเรื่องธรรมชาติและความคิดนี้ใช้กับการเขียนโปรแกรมแบ่งออก
tdammers

1
ดังนั้นคำถามหลักคือ หากไฟล์สามารถปิดตัวเองได้อาร์เรย์สามารถเรียงลำดับตัวเอง ฯลฯ ทำไมถุงเจาะไม่สามารถเจาะได้เอง? มีความแตกต่างจริงหรือเป็นเพียงแค่ในกรณีแรกเราคุ้นเคยกับมันและในครั้งที่สองเราไม่ได้?
clime

6

ฉันคิดว่ามันเป็นปัญหาทางความคิด (วิธีที่เราคิดเกี่ยวกับโลก) ไม่เป็นไรที่จะพูดว่า:

  • ดูประตูกำลังจะปิด door.close()
  • ว้าวกระดาษพับไปเอง paper.fold()
  • อะไรกันเนี่ย! ไฟล์นั้นบนโต๊ะเพิ่งปิดไม่มีใครอยู่รอบ ๆ file.close()

มันแปลกที่จะพูดว่า:

  • กระเป๋าเจาะในโรงยิมเพิ่งจะต่อย bag.punch()

มันจะต้องมีบางสิ่งบางอย่างที่จะเจาะตัวเองด้วยในสถานที่แรก (เช่นแขน) คุณอาจจะพูดว่า:

  • กระเป๋าเจาะได้เริ่มเคลื่อนไหวด้วยตัวเองเหมือนใครบางคนจะได้เจาะมัน punching_bag.move()

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


2

ฉันคิดว่ามันเป็นเรื่องของรสนิยม Punching bag's punch()วิธีการอย่างน้อยสอดคล้องกับfile.close()หรือframe.move()ในความหมายของการดำเนินการประสบกับตัวเอง คำถามส่วนใหญ่จะเป็นเพราะเหตุใดจึงBoxerมีpunch(something)วิธีการทั้งหมด?


ฉันชอบจุดของคุณเกี่ยวกับ file.close () นั่นคือสิ่งที่ฉันได้รับ นักมวยอาจมีวิธีการชกเพราะยังมีโค้ชฝึกมวย ในความเป็นจริงฉันแค่พยายามยกตัวอย่างของการกระทำ (ข้อความ) ที่ถูกส่งผ่านวัตถุต่าง ๆ โดยที่สิ่งสุดท้ายคือ "วัตถุของการกระทำ" ฉันมีปัญหาเล็กน้อยกับ list.append (4), account.deposit (50), file.close (), paper.fold () เทียบกับ boxer.punch (), dog.bark (), logger.log () ฯลฯ .
clime

เมื่อผ่านวัตถุหลายอย่างมี 2 กรณี: คุณใช้บริบทที่ถูกผูกไว้ (ตัวเอง) และคุณทำไม่ได้ ถ้าคุณทำวิธีของคุณควรจะCoach.sayPunchToBoxer(), และBoxer.punchNearestBag() มิฉะนั้นคุณต้องคาดเดาสิ่งที่จะเกิดขึ้นทุกครั้งที่คุณโทรBag.punch() Coach.punch()กฎทั่วไปคือ: หากไม่ได้ระบุวัตถุที่ประสบกับการกระทำในชื่อเมธอดผู้รับจะเป็นวัตถุนั้น

ฉันคิดว่านี่ก็ใช้ได้เหมือนกัน: coach.say_punch (นักมวย, punching_bag), boxer.punch (punching_bag) ตัวรับสัญญาณ ie ไม่ได้อยู่ในชื่อเมธอด แต่อยู่ในพารามิเตอร์
clime

1
แน่นอนว่าฉันหมายถึงผู้รับสัญญาณแอคชั่นควรจะคาดเดาได้จากคำสั่งการโทร

2

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

ความชอบของฉันคือการรักษาpunch(boxer, object, strength)และเปลี่ยนชื่อวิธีตรงกันข้ามให้punchedเป็น คุณสามารถโทรหามันhandle_punchหรืออะไรทำนองนั้น แต่ก็ยังคลุมเครือไม่ว่าจะจัดการกับคำสั่งหมัดหรือการแจ้งเตือนว่ามันถูกเจาะ


จุดที่ดีเกี่ยวกับนักมวยที่ต้องการทั้งหมัดและบางอย่างเช่น handle_punch (อาจเป็นdefendในกรณีนี้โดยเฉพาะ) แต่กระเป๋าเจาะจะไม่เป็นแบบสองทิศทางเช่นนั้น และมีไฟล์นี้อยู่แล้วปิด () ...
clime

defendเป็นคำสั่ง เป็นการกระทำที่เป็นไปได้อย่างหนึ่งที่วัตถุสามารถตอบสนองได้punchedแต่คุณไม่ต้องการให้วัตถุอื่นเรียกใช้defendโดยตรง
user2313838

2

วิธีการของคุณในที่สุดจะนำไปสู่รหัสคู่มาก

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

ฉันอยากจะทำแบบจำลองนี้เป็นนักมวยที่สร้างหมัด (วัตถุอื่นที่มีกำลังของแอ็ตทริบิวต์ของหมัด, เข้าถึง, ทิศทางและอื่น ๆ )

จากนั้นเตรียมกระเป๋าเจาะด้วยวิธีการเช่น onPunch ซึ่งได้รับวัตถุเจาะนี้สามารถคำนวณผลกระทบของการเจาะด้วยตัวเอง

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

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


1

นี่เป็นปัญหาที่ฉันเรียกว่า "object / subject" สับสนและค่อนข้างแพร่หลาย

ประโยคโดยทั่วไปจะมีเรื่องที่ไม่กริยาในเป้าหมายของพวกเขาวัตถุ

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

ซึ่งหมายความว่าวิธีการดำเนินการกับพวกเขาพวกเขาเป็นเป้าหมายของการกระทำที่ไม่ได้กระทำ นั่นเป็นเหตุผลที่เราเรียกพวกเขาว่า "วัตถุ" ไม่ใช่ "วิชา"!

เมื่อคุณพูดว่าFile.closeไม่ใช่ไฟล์ที่ปิดตัวเองมันเป็นเธรดที่กำลังรันอยู่ในปัจจุบันซึ่งปิดไฟล์ ถ้าคุณบอกว่าArray.sortเธรดที่กำลังรันอยู่จะเรียงลำดับอาร์เรย์ ถ้าคุณบอกว่าHttpServer.sendRequestเธรดที่กำลังรันอยู่ในปัจจุบันจะส่งคำขอไปยังเซิร์ฟเวอร์ (ไม่ใช่ในทางกลับกัน!) ในทำนองเดียวกันการพูดPunchingBag.punchหมายถึงด้ายที่ใช้อยู่ในปัจจุบันเจาะถุง

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

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


0

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

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

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


3
isPunchedมันทำให้เข้าใจผิดจริงๆ (มากหรือน้อยขึ้นอยู่กับรูปแบบการตั้งชื่อกรอบ)

เป็นเรื่องปกติที่จะใช้วิธีการกับวัตถุนั้นซึ่งมันถูกเรียกว่า มีอะไรผิดปกติpunch()หรือ

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

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

-2

hmmmm ฉันกำลังซักถามกระเป๋าเจาะเป็นชั้นเรียนเพราะคุณไม่สนใจกระเป๋าเจาะ - คุณใส่ใจเกี่ยวกับผลกระทบและความแข็งแกร่งของกำปั้นนักมวย ดังนั้นวิธีการที่ควรจะเกี่ยวกับสิ่งที่วัดและรายงานผลกระทบของหมัด แม้ว่านี่จะมาจาก 'punching bag' การตั้งชื่อก็ยังควรเปิดเผยความรับผิดชอบเช่น punchImpactMeter เป็นต้น


-3

นักมวยทำการชกต่อยกระเป๋า -> boxer.punch

กระเป๋าเจาะได้รับการเจาะโดยนักมวย -> punchingbag.get_punch


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