ข้อแตกต่างระหว่าง“ Java OOP” และ“ Pythonic OOP” หรือไม่? [ปิด]


19

ฉันเริ่มต้นด้วย ActionScript 2.0 แล้วจึงไปกับ Java ฉันเรียนรู้หรืออย่างน้อยก็ใช้หลายภาษาตั้งแต่นั้นมารวมถึง Python (อาจเป็นภาษาที่ฉันชอบ)

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

คำตอบ:


54

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

สำหรับคนที่แต่งตัวประหลาด Python Java เป็นจักรวาล Orwellian ที่คุณถูกผูกมัดอย่างต่อเนื่องเพื่อดูคนอื่นลดลงของวิธีการที่จักรวาลติ๊ก

ความจริงคือทุกสิ่งที่คุณสามารถทำได้ในภาษาหนึ่งที่คุณสามารถทำได้ในอีกภาษาหนึ่งอย่างหมดจด อย่างไรก็ตามตามที่คุณได้กล่าวมามีความแตกต่างที่สำคัญในชุมชนทั้งสองว่าความสะอาดหมายถึงอะไร

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

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

แทบจะไม่เคยมีวิธีที่ง่ายและรวดเร็วในการทำสิ่งต่าง ๆ ใน Java แต่ IDE และเครื่องมือจะช่วยให้คุณทำงานได้อย่างเจ็บปวดเพียงไม่กี่คลิก

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

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

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

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

ดังนั้นการถกเถียงกันอย่างเผ็ดร้อนว่าเป็นสิ่งที่ดีที่สุด


14

คุณรู้หรือไม่ว่าการตั้งค่าการมองเห็นวิธีการและตัวแปรทั้งหมด ใช่สิ่งเหล่านั้นไม่มีอยู่อีกต่อไปทุกอย่างเป็นที่เปิดเผย มีการตั้งชื่อแบบแผนและชื่อ mangling แต่ทุกอย่างยังคงมีอยู่

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

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

# bad
def fL(x=[])
  x.append(1)
  print x
# good
def fN(x=None)
  if (x is None):
    x = []
  x.append(1)
  print x

fL()
fL()
fN()
fN()

ความแตกต่างระหว่างตัวแปรคลาสและอินสแตนซ์นั้นบอบบางมากเมื่อคุณเริ่มใช้งานครั้งแรก

class Obj(object):
   thing = "class variable"
   def __init__(self):
      self.thing1 = "instance variable"
      print self.thing, self.thing1

นี่คือบางสิ่งที่ฉันต้องคุ้นเคยเมื่อฉันเปลี่ยน


1
+1 สรุปที่ดีของบางสิ่งบางอย่างแม้ว่าฉันจะรู้สิ่งเหล่านั้นมาก่อน
Anto

6

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

แต่ตราบใดที่รหัส OO ไปมีพื้นฐานบางอย่างที่ไม่ควรเปลี่ยนจากภาษาเป็นภาษา: คุณควรพยายามเขียนโค้ดที่เป็นขี้อายและ DRY เสมอไม่ว่าคุณจะเขียนใน Applescript, Python, Java หรือ C ++

---- ---- แก้ไข

@delnan ชี้ให้เห็นอย่างชัดเจนจริง ๆ แล้วมีห้าชนิดข้อมูลคอมโพสิตที่กำหนดโดย Python ที่ระดับเคอร์เนล (รายการ, dict, tuple, set, และ frozenset ตามสำเนาของ "Python ใน Nutshell") แม้ว่าสิ่งนี้จะเป็นจริง แต่ก็ไม่เกี่ยวข้องกับจุดที่ฉันพยายามทำ: Python สร้างรายการเป็นโครงสร้างข้อมูลที่จำเป็น ใช่คุณสามารถใช้รายการเป็นสแต็ก แต่คุณสามารถใช้รายการเดียวกันกับคิวได้ แล้วก็สแต็คอีกครั้ง

Java ในอีกด้านหนึ่งมีโครงสร้างข้อมูลเคอร์เนล (Array อ้างอิงจาก "The Java Pocket Guide) แต่โดยทั่วไปแล้วคุณไม่สามารถทำอะไรได้มากใน Java โดยไม่นำเข้าคอลเลกชันเมื่อคุณทำเช่นนั้นคุณจะสามารถเข้าถึงได้ เป็นห้องสมุดประเภท 'รวย' (ซึ่งหมายถึงฉันหมายถึงความซับซ้อนอย่างมาก) ซึ่งจะได้รับฟังก์ชั่นการทำงานแบบเดียวกับที่คุณมีในรายการ Python

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

ข้อแตกต่างประการหนึ่งคือคุณไม่สามารถป๊อปไอเท็มจาก Java Queue และคุณไม่สามารถผ่านออบเจ็กต์ Java Queue ที่ใดก็ได้ที่ต้องการรายการ Java Linked List ดังนั้นบางทีโดย "รวย" ฉันหมายถึง "แข็ง"

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

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


ฉันคุ้นเคยกับทุกอย่างยกเว้น metaclasses จะค้นหาพวกเขา ขอบคุณ :)
Anto

7
-1 จนกว่าคุณจะสามารถอธิบายสิ่งต่อไปนี้: (1) "Python เพิ่งมีรายการ" - Python มีโครงสร้างข้อมูลมากมาย มันไม่ได้มีการใช้งานสามโครงสร้างข้อมูลทุก ๆ ที่เคยคิด แต่ยังเกี่ยวกับทุก ๆ คนส่วนใหญ่จะต้องการ (2) การเรียกระบบชนิดของ Java "รวย" เป็นคำเยาะเย้ยของระบบประเภทที่ซับซ้อนเหล่านั้นจริงๆ สำหรับผู้เริ่มดูที่ Haskell (98 โดยไม่มีนามสกุล)

ฉันขอโทษนี่แค่ไม่เป็นความจริง Python มีโครงสร้างข้อมูลสองรายการ: รายการและพจนานุกรม Python LIBRARIES บางตัวอาจขยายโครงสร้างแกนหลักเหล่านี้ แต่นั่นไม่เหมือนกับที่บอกว่ามีภาษาอยู่
philosodad

5
มีจำนวนคำตอบสองเท่าแล้ว รายการทวีคูณเป็นสแต็ก ชุดและทูเปิลนั้นมีอยู่แล้วในตัว (มีโครงสร้างข้อมูลจำนวนเท่าใดที่ติดตั้งไว้ใน Java?) นอกจากนี้ยังมีโมดูลในไลบรารีมาตรฐานสำหรับกอง (นาที -) heaps, deques, เรคคอร์ดที่ไม่เปลี่ยนรูปและอาร์เรย์ที่เป็นเนื้อเดียวกัน ชนิด) และนั่นเป็นเพียงส่วนบนของหัวของฉัน ใช่ส่วนใหญ่ใช้รายการ / dicts ภายใน (อย่างไรก็ตามชุดไม่ได้ dicts ด้วยคีย์ที่ไม่ได้ใช้) แต่เป็นคอลเลกชันส่วนใหญ่ใน Java - ในความเป็นจริงในทุกภาษา มันเป็นวิธีการทำงาน

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