ไหนดีกว่า: กลุ่ม getters หรือ 1 เมธอดที่มีพารามิเตอร์สตริงการเลือก?


15

โดเมนความรู้ของเราเกี่ยวข้องกับคนที่เดินข้ามแผ่นบันทึกความกดดันด้วยเท้าเปล่า เราทำการจดจำรูปภาพซึ่งส่งผลให้วัตถุของคลาส 'เท้า' หากเท้ามนุษย์ถูกจดจำในข้อมูลเซ็นเซอร์

มีการคำนวณหลายอย่างที่ต้องดำเนินการกับข้อมูลของเท้า

ตอนนี้ API ตัวไหนจะดีกว่า:

class Foot : public RecognizedObject  { 
  MaxPressureFrame getMaxPressureFrame();
  FootAxis getFootAxis();
  AnatomicalZones getAnatomicalZones();

  // + similar getters for other calculations

  // ...
}

หรือ:

class Foot : public RecognizedObject {
  virtual CalculationBase getCalculation(QString aName);

  // ...
}

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

คำแนะนำใด ๆ?

โปรบางตัวสำหรับวิธีแรกอาจเป็น:

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

แย้งบางส่วนของ:

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

โปรบางตัวสำหรับแนวทางที่สอง:

  • ยืดหยุ่นมากขึ้น
  • api มีโอกาสน้อยที่จะเปลี่ยนแปลง (สมมติว่าเราได้นามธรรมถูกต้องถ้าไม่การเปลี่ยนแปลงจะมีค่าใช้จ่ายมากขึ้น)

แย้งบางส่วนของ:

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

5
คุณสามารถสร้างenumและเปลี่ยนเป็นค่าได้ ยังฉันคิดว่าตัวเลือกที่สองคือความชั่วร้ายเพราะมันเบี่ยงเบนจาก KISS
Vorac

ยากที่จะค้นหาการใช้งานทั้งหมดของการคำนวณเฉพาะหากคุณใช้พารามิเตอร์สตริงเพื่อทริกเกอร์ ยากที่จะเป็น 100% คุณพบพวกเขาทั้งหมด
Konrad Morawski

ใช้เวลาที่ดีที่สุดของโลกทั้งสองและเขียนfaçadeกับพวงของ getters getCalculation()ตื่นตาตื่นใจ
nalply

1
Enums ดีกว่าสายแน่นอน! ฉันไม่ได้คิดถึงสิ่งนี้ พวกเขา จำกัด API และป้องกันการละเมิดพารามิเตอร์สตริง (เช่น concat ของโทเค็นและอึอื่น ๆ ) ดังนั้นฉันเดาการเปรียบเทียบระหว่างตัวเลือกที่ 1 และตัวเลือกที่ 2 กับ Enum แทนที่จะเป็นสตริง
Bgie

คำตอบ:


6

ฉันคิดว่าในวิธีแรกจะชำระ สตริง Magic สามารถสร้างปัญหาต่อไปนี้: ข้อผิดพลาดในการพิมพ์ผิดประเภทความปลอดภัยกลับมาเล็กน้อย, การขาดรหัสที่สมบูรณ์รหัสไม่ชัดเจน (รุ่นนี้มีคุณสมบัติที่ไม่ได้หรือไม่ฉันเดาว่าเราจะหาได้ที่ runtime) การใช้ enums จะแก้ไขปัญหาเหล่านั้นได้บ้าง แต่ลองดูข้อเสียที่คุณยกมา:

  • จำนวนผู้ได้รับจะเพิ่มขึ้นตามการคำนวณใหม่ทุกครั้งที่เราประดิษฐ์ได้รับเพิ่มในรายการ

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

  • API มีแนวโน้มที่จะเปลี่ยนแปลงมากขึ้นและหากมีการแนะนำให้ใช้การเปลี่ยนแปลงแบบแบ่งย่อยเราจำเป็นต้องมี API รุ่นใหม่คือ Foot2

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

  • ในกรณีที่นำคลาสกลับมาใช้ใหม่ในโครงการอื่นเราอาจไม่ต้องการการคำนวณทุกครั้ง

ฉันไม่เห็นว่าการใช้สายเวทหรือ enums จะช่วยได้อย่างไรถ้าฉันเข้าใจอย่างถูกต้องคุณอาจรวมรหัสในคลาส Foot หรือคุณแบ่งมันเป็นคลาสย่อย ๆ สองสามตัว


ฉันชอบแนวคิด API บางส่วนที่มีอินเตอร์เฟสดูเหมือนว่าจะเป็นหลักฐานในอนาคต ฉันจะไปกับคนนั้น ขอขอบคุณ. หากมันกลายเป็นความยุ่งเหยิงมากเกินไป (การติดตั้งอินเตอร์เฟสมากเกินไป) การใช้คลาสอะแดปเตอร์ขนาดเล็กหลาย ๆ คลาสจะมีความยืดหยุ่นมากขึ้น: หากมีการเดินเท้าหลายรูปแบบด้วย api ที่แตกต่างกัน (เช่นเท้า, เท้ามนุษย์ เพื่อให้แต่ละวิดเจ็ต GUI สามารถทำงานร่วมกันได้กับทุกคน ...
Bgie

ข้อดีของการใช้ตัวเลือกคำสั่งคือสามารถมีการนำไปใช้ที่ได้รับคำสั่งซึ่งไม่เข้าใจการเรียกใช้เมธอดตัวช่วยแบบคงที่ที่มาพร้อมกับอินเตอร์เฟส หากคำสั่งแสดงถึงสิ่งที่สามารถทำได้กับการใช้งานเกือบทั้งหมดโดยใช้วิธีการทั่วไป แต่การใช้งานบางอย่างอาจทำได้โดยใช้วิธีที่ดีกว่า [พิจารณาเช่นIEnumerable<T>.Count] วิธีการดังกล่าวอาจอนุญาตให้โค้ดได้รับประโยชน์ด้านประสิทธิภาพของใหม่ คุณลักษณะส่วนต่อประสานเมื่อใช้งานแอพพลิเคชั่นที่รองรับพวกเขา
supercat

12

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

class Foot : public RecognizedObject {
public:
    // Rather low-level API to access all characteristics that might be needed by a calculation
};

class MaxPressureFrame {
public:
    MaxPressureFrame(const Foot& aFoot); // Performs the calculation based on the information in aFoot
    //API for accessing the results of the calculation
};

// Similar classes for other calculations

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


แน่นอนกว่าตัวเลือกที่ 1 และ 2 นี่เป็นเพียงขั้นตอนสั้น ๆ จากการใช้รูปแบบการออกแบบกลยุทธ์
Brian

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

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

@Bgie: ด้วยการพึ่งพาระหว่างการคำนวณฉันเห็นด้วยกับ @ user116462 ว่าตัวเลือกแรกดีที่สุด”
Bart van Ingen Schenau
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.