นักพัฒนา Python ถกเถียงว่า Pydantic ควรอยู่นอก Domain Logic หรือไม่

ทีมชุมชน BigGo
นักพัฒนา Python ถกเถียงว่า Pydantic ควรอยู่นอก Domain Logic หรือไม่

การอภิปรายล่าสุดในชุมชน Python ได้จุดประกายการถกเถียงเกี่ยวกับแนวปฏิบัติที่ดีในการออกแบบสถาปัตยกรรมเมื่อใช้ Pydantic ซึ่งเป็นไลบรารีสำหรับตรวจสอบข้อมูลที่ได้รับความนิยม การสนทนามีจุดศูนย์กลางอยู่ที่ว่านักพัฒนาควรจำกัด Pydantic models ไว้เฉพาะขอบเขตของแอปพลิเคชันหรือควรให้แพร่กระจายไปทั่วทั้งโค้ดเบส รวมถึงส่วนหลักของ domain logic

คำถามหลักเกี่ยวกับสถาปัตยกรรม

ประเด็นหลักเกี่ยวข้องกับการแยกส่วนของความรับผิดชอบในแอปพลิเคชันขนาดใหญ่ นักพัฒนาบางคนสนับสนุนการเก็บ Pydantic models ไว้เฉพาะขอบของแอปพลิเคชัน - ในชั้น API และอินเทอร์เฟซข้อมูลภายนอก - ขณะที่ใช้ dataclasses หรือ objects ของ Python ธรรมดาสำหรับ business logic ภายใน แนวทางนี้เป็นไปตามหลักการของ clean architecture ที่ชั้น domain จะต้องเป็นอิสระจากไลบรารีและเฟรมเวิร์กภายนอก

อย่างไรก็ตาม ชุมชนมีความเห็นแตกแยกว่าการแยกส่วนนี้ให้ประโยชน์จริงหรือเพียงแค่สร้างความซับซ้อนที่ไม่จำเป็น นักวิจารณ์โต้แย้งว่าการรักษา data models แยกกันนำไปสู่โค้ด boilerplate ที่มากเกินไปและ mapping logic ระหว่างการแสดงข้อมูลที่แตกต่างกันของข้อมูลเดียวกัน พวกเขาตั้งคำถามว่าประโยชน์ในทางทฤษฎีของ loose coupling สมควรกับค่าใช้จ่ายในทางปฏิบัติของการรักษา object types หลายประเภทหรือไม่

ข้อพิจารณาด้านประสิทธิภาพและการปฏิบัติ

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

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

การเปรียบเทียบประสิทธิภาพ:

  • โมเดล Pydantic : มีค่าใช้จ่ายในการสร้าง instance แพงกว่าคลาส Python ปกติถึง 8 เท่า
  • การเข้าถึง attribute: ช้ากว่าคลาสมาตรฐาน 50%
  • Dataclasses: เร็วกว่า Pydantic 2 เท่าในการสร้างออบเจ็กต์
  • Compiled dataclasses (ด้วย mypyc ): ปรับปรุงประสิทธิภาพได้ถึง 10 เท่าเมื่อเทียบกับ Pydantic

แนวทางทางเลือกและเครื่องมือ

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

ประโยชน์ที่ใหญ่ที่สุดที่คุณได้รับคือความสามารถในการมีความยืดหยุ่นมากขึ้นในการตรวจสอบเมื่อ input model ไม่เหมือนกับ database model

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

ไลบรารีทางเลือกที่ได้รับการกล่าวถึง:

  • Dacite: แปลง dictionary เป็น nested dataclasses โดยออกแบบมาเฉพาะสำหรับการเริ่มต้น object hierarchies ที่ซับซ้อน
  • Marshmallow: ไลบรารี serialization/validation รุ่นเก่า ถือว่ามีความซับซ้อนน้อยกว่า Pydantic
  • SQLModel: รวม Pydantic เข้ากับ SQLAlchemy สำหรับการทำงานกับฐานข้อมูล
  • Protobuf: รูปแบบ binary serialization ที่แปลงเป็น Python dataclasses, JSON และ binary strings

บทสรุป

การถกเถียงสะท้อนความตึงเครียดที่กว้างขึ้นในสถาปัตยกรรมซอฟต์แวร์ระหว่างความเป็นจริงและแนวปฏิบัติที่ดีในทางทฤษฎี ในขณะที่หลักการของ clean architecture แนะนำให้เก็บ dependencies ภายนอกออกจาก core business logic ประโยชน์ในทางปฏิบัติต้องชั่งน้ำหนักกับความซับซ้อนเพิ่มเติมและค่าใช้จ่ายในการพัฒนา ชุมชน Python ยังคงต่อสู้กับการหาสมดุลที่เหมาะสมระหว่างความบริสุทธิ์ของสถาปัตยกรรมและประสิทธิภาพของนักพัฒนา โดยไม่มีฉันทามติที่ชัดเจนเกี่ยวกับแนวทางที่ดีที่สุดสำหรับทุกสถานการณ์

อ้างอิง: Keep Pydantic out of your Domain Layer