มี antipattern เพื่ออธิบายวิธีการเข้ารหัสนี้หรือไม่? [ปิด]


26

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

ErrorLog.Log(ex, "friendly message");

เขาเพิ่มวิธีการอื่น ๆ อีกมากมายเพื่อให้งานเดียวกันนั้นสำเร็จ เช่น

SomeClass.Log(ex, "friendly message");

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


36
"แย่เข้ารหัส" ครอบคลุมมัน;)
Oded

12
ขึ้นอยู่กับ มันเป็น wrapper สำหรับไลบรารีการบันทึกหรือไม่? ถ้ามีเคยเป็นโอกาสที่มันอาจจะสลับนี้จริงเป็นวิธีที่ดี ...
Rig

3
@lortabac: ปัญหาเกี่ยวกับ "รหัส baklava" คือมันฟังดูดีและอร่อยและเป็นที่ต้องการ
FrustratedWithFormsDesigner

10
โปรแกรมเมอร์นี้พูดอะไรเมื่อคุณเพิ่มเหตุผลที่เพิ่มวิธีการเหล่านี้? การทำความเข้าใจเหตุผลของพวกเขาควรทำให้ง่ายขึ้นในการให้ความรู้แก่พวกเขา
Keith

3
เสียงเหมือนระดับของการอ้อมซึ่งอาจทำได้ดีเมื่อคุณต้องการหลีกเลี่ยงการแต่งงานระหว่างสองคลาสตามที่ @Rig ชี้ให้เห็น บางทีมันอาจจะเป็นแค่ coder ที่ทุกข์ทรมานจากpatternitis - ลองใช้รูปแบบบางอย่างเพื่อแก้ปัญหาที่ไม่ได้อยู่ที่นั่นและละเมิด KISS
Fuhrmanator

คำตอบ:


54

มันคุ้มค่าที่จะเรียกนิสัยการเขียนโค้ดที่ไม่ดีว่า Antipattern ถ้ามันมีการแพร่กระจายอย่างสมเหตุสมผล

ที่เหลือเราแค่เรียก "รหัสขยะ" ...


ถ้าฉันจะแนะนำชื่อสำหรับนิสัยที่ไม่ดีนี้โดยเฉพาะมันจะเป็น "ความผิดปกติที่เป็นนามธรรมครอบงำ" :-)


9
ฉันมักจะใช้ "Indirection Hell"
Dan Neely

27

ไม่มันไม่ใช่รูปแบบต่อต้าน แต่ฉันจะยกประเด็นต่อไปนี้

การละเมิดหลักการความรับผิดชอบเดี่ยว

SRP กล่าวว่าคลาสควรมีเหตุผลหนึ่งประการที่จะเปลี่ยนแปลง การเพิ่มเมธอดตัวบันทึกหมายความว่าคลาสต้องเปลี่ยนหากตรรกะการล็อกควรเปลี่ยน

การละเมิดis-aความสัมพันธ์

คลาสพื้นฐานไม่ใช่กล่องเครื่องมือที่คุณสามารถเพิ่มวิธีอำนวยความสะดวกได้หลายวิธี

การทำเช่นนี้จะทำให้คู่คลาสที่สืบทอดมามีผลกับการใช้งานที่คลาสฐานมี

เปรียบเทียบกับองค์ประกอบ


1
"ปัญหาความรับผิดชอบเดี่ยว"? SRP? บางทีคุณตั้งใจจะเขียนหลักการความรับผิดชอบเดี่ยว? เพียงเชื่อมต่อทั้งสองที่นี่ :)
zxcdw

8

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

สิ่งที่ต้องพิจารณา


7

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


3
ฉันยังได้ยิน "รหัสหัวหอม" เพื่ออธิบายสิ่งเดียวกัน
Justin Niessner

4

ฉันไม่แน่ใจว่าจะอธิบายเรื่องนี้เป็นความผิดของหลักการความรับผิดชอบเดียวเพราะหากมีการเปลี่ยนแปลงลายเซ็นวิธีการ ErrorLog (วิธีที่เรียกว่า SomeClass) ทุกรหัสลูกค้าที่เรียกวิธีนี้จะล้มเหลว

เห็นได้ชัดว่ามีวิธีการใช้การสืบทอด (หรือการสร้างคลาสที่ต้องมีการบันทึกการใช้งานอินเตอร์เฟซการบันทึก) ที่นั่น


ยังคงเป็นการปฏิบัติที่ไม่ดีเพราะ: 1) ไม่น่าจะเปลี่ยนแปลง 2) หากมีการเปลี่ยนแปลงพวกเขาก็สามารถสร้างคลาส wrapper ที่มีชื่อเดียวกันและเปลี่ยนการนำเข้า
วินไคลน์

2
+1 และนี่คือ "ลุงบ๊อบ" (โรเบิร์ตมาร์ติน) โต้เถียงกันในเรื่องของการพึ่งพาการรวมศูนย์ในจำนวนโมดูลที่ จำกัด แทนที่จะกระจัดกระจายผ่านโค้ด
MarkJ

3

หรือเราอาจมองว่านี่เป็น "ช่วงเวลาที่สอนได้" :)

นักพัฒนาของคุณอาจเป็นความคิดที่ดี สมมติว่าคุณต้องการมีข้อกำหนดว่าวัตถุธุรกิจทั้งหมดของคุณมีความสามารถในการบันทึกอัจฉริยะ คุณอาจกำหนด:

   public interface IBusinessObjectLogger
   {
       void Log(Exception ex, string logMessage)
   }

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


3

ฉันไม่แน่ใจว่านี่เป็นสิ่งที่ชั่วร้ายโดยอัตโนมัติ

ถ้าคุณโทรหา SomeClass.Log แน่นอนที่สุดคือความชั่วร้าย แต่ถ้า Log ถูกใช้จาก WITHIN SomeClass เท่านั้นมันจะลดการเชื่อมต่อและฉันจะเรียกมันว่ายอมรับได้


2

นี่เป็นเรื่องธรรมดาในบางรูปแบบการเขียนโค้ดและพื้นฐานของแนวความคิดไม่ใช่ในรูปแบบต่อต้าน

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


2

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

http://en.wikipedia.org/wiki/Accidental_complexity


1

มันอาจจะเป็นการละเมิด / ความเข้าใจผิดของรูปแบบอาคาร ฉันเห็นสิ่งที่คล้ายกันใน codebase ที่ฉันทำงานด้วย นักพัฒนาต้องผ่านช่วงเวลาที่พวกเขาคลั่งไคล้กับรูปแบบการออกแบบโดยไม่เข้าใจหลักการที่ครอบคลุมของการออกแบบ OO

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


1

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

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


0

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


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

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