ฉันได้ดูคำตอบและค้นหาใน Google แล้ว แต่ฉันไม่พบสิ่งที่เป็นประโยชน์ (เช่นนั่นจะไม่มีผลข้างเคียงที่น่าอึดอัดใจ)
ปัญหาของฉันในเชิงนามธรรมคือฉันมีวัตถุและจำเป็นต้องดำเนินการลำดับที่ยาวนานของมัน ฉันคิดว่ามันเป็นสายการประกอบเช่นการสร้างรถ
ผมเชื่อว่าวัตถุเหล่านี้จะเรียกว่าวิธีวัตถุ
ดังนั้นในตัวอย่างนี้ในบางครั้งฉันจะมี CarWithoutUpholstery ซึ่งฉันจะต้องเรียกใช้ installBackSeat, installFrontSeat, installWoodenInserts (การดำเนินการไม่รบกวนซึ่งกันและกันและอาจทำได้ในแบบคู่ขนาน) การดำเนินการเหล่านี้ดำเนินการโดย CarWithoutUpholstery.worker () และให้ผลลัพธ์เป็นวัตถุใหม่ซึ่งจะเป็น CarWithUpholstery ซึ่งฉันจะเรียกใช้ cleanInsides (), validNoUpholsteryDefects () และอื่น ๆ
การดำเนินงานในเฟสเดียวนั้นมีความเป็นอิสระอยู่แล้วเช่นฉันกำลังต่อสู้กับส่วนย่อยของพวกเขาที่อาจดำเนินการในลำดับใด ๆ (ที่นั่งด้านหน้าและด้านหลังอาจติดตั้งในลำดับใดก็ได้)
ตรรกะของฉันในปัจจุบันใช้ Reflection เพื่อความง่ายในการใช้งาน
นั่นคือเมื่อฉันมี CarWithoutUpholstery วัตถุจะตรวจสอบตัวเองสำหรับวิธีที่เรียกว่า performSomething () ณ จุดนั้นมันรันวิธีการเหล่านี้ทั้งหมด:
myObject.perform001SomeOperation();
myObject.perform002SomeOtherOperation();
...
ในขณะที่ตรวจสอบข้อผิดพลาดและสิ่งต่างๆ ในขณะที่คำสั่งของการดำเนินงานเป็นสำคัญผมได้รับมอบหมายเพื่อทำพจนานุกรมในกรณีที่ผมเคยค้นพบคำสั่งบางเป็นสิ่งสำคัญหลังจากทั้งหมด สิ่งนี้ขัดแย้งกับYAGNIแต่มีค่าใช้จ่ายน้อยมาก - การเรียงลำดับแบบง่าย ๆ () - และมันสามารถบันทึกวิธีการเปลี่ยนชื่อจำนวนมาก
ตัวอย่างที่แตกต่าง
ให้เราบอกว่าแทนการสร้างรถผมต้องรวบรวมรายงานตำรวจลับเกี่ยวกับใครสักคนและส่งไปยังของฉันชั่วร้ายนเรศวร วัตถุสุดท้ายของฉันคือ ReadyReport เพื่อสร้างมันฉันเริ่มต้นด้วยการรวบรวมข้อมูลพื้นฐาน (ชื่อนามสกุลคู่สมรส ... ) นี่คือระยะของฉัน A. ขึ้นอยู่กับว่ามีคู่สมรสหรือไม่ฉันอาจต้องดำเนินการขั้นตอนที่ B1 หรือ B2 และรวบรวมข้อมูลเรื่องเพศในหนึ่งหรือสองคน สิ่งนี้ทำจากข้อความค้นหาที่แตกต่างกันหลายอย่างสำหรับ Evil Minions ที่แตกต่างกันในการควบคุมชีวิตกลางคืน, กล้องวงจรปิด, ใบเสร็จรับเงินจากร้านขายเซ็กซ์และสิ่งที่ไม่ และอื่น ๆ และอื่น ๆ.
หากเหยื่อไม่มีครอบครัวฉันจะไม่เข้าสู่ขั้นตอน GetInformationAboutFamily แต่ถ้าฉันทำมันก็ไม่เกี่ยวข้องเลยว่าฉันจะกำหนดเป้าหมายไปที่พ่อหรือแม่หรือพี่น้อง (ถ้ามี) ก่อน แต่ฉันไม่สามารถทำเช่นนั้นได้หากฉันไม่ได้ทำ FamilyStatusCheck ซึ่งเป็นของเฟสก่อนหน้า
มันทำงานได้อย่างยอดเยี่ยม ...
- ถ้าฉันต้องการการดำเนินการเพิ่มเติมฉันต้องเพิ่มวิธีการส่วนตัวเท่านั้น
- หากการดำเนินการเป็นเรื่องธรรมดาสำหรับหลาย ๆ เฟสฉันสามารถรับมันจากซูเปอร์คลาส
- การดำเนินงานง่ายและอยู่ในตัวเอง คุ้มค่าจากการดำเนินงานอย่างใดอย่างหนึ่งไม่เคยต้องตามคนอื่น ๆ (การดำเนินงานที่ไม่ได้รับการดำเนินการในขั้นตอนที่แตกต่างกัน)
- วัตถุที่อยู่ในบรรทัดไม่จำเป็นต้องทำการทดสอบหลายอย่างเนื่องจากไม่สามารถมีอยู่ได้หากวัตถุผู้สร้างไม่ได้ตรวจสอบเงื่อนไขเหล่านั้นตั้งแต่แรก กล่าวคือเมื่อมีการวางแทรกในแดชบอร์ดทำความสะอาดแผงควบคุมและการตรวจสอบแดชบอร์ดที่ฉันไม่จำเป็นต้องตรวจสอบว่าเป็นจริงแดชบอร์ดมี
- ช่วยให้ทดสอบง่าย ฉันสามารถจำลองวัตถุบางส่วนได้อย่างง่ายดายและเรียกใช้วิธีการใด ๆ กับมันและการดำเนินการทั้งหมดเป็นกล่องดำที่กำหนด
...แต่...
ปัญหาเกิดขึ้นเมื่อฉันเพิ่มการดำเนินการครั้งสุดท้ายหนึ่งในวัตถุวิธีหนึ่งของฉันซึ่งทำให้โมดูลโดยรวมเกินดัชนีความซับซ้อนบังคับ ("น้อยกว่าวิธีส่วนตัว N")
ฉันได้ดำเนินเรื่องนี้ขึ้นไปแล้วและเสนอว่าในกรณีนี้ความมั่งคั่งของวิธีการส่วนตัวไม่ได้เป็นเรื่องของภัยพิบัติ ความซับซ้อนคือมี แต่มันเป็นเพราะมีการดำเนินการเป็นที่ซับซ้อนและที่จริงก็ไม่ได้ทั้งหมดที่ซับซ้อน - เป็นเพียงยาว
จากการใช้ตัวอย่าง Evil Overlord ปัญหาของฉันคือ Evil Overlord (หรือผู้ที่ไม่ถูกปฏิเสธ ) ที่ได้รับการร้องขอข้อมูลด้านโภชนาการทั้งหมด Minions การกินของฉันบอกฉันว่าฉันต้องการสอบถามร้านอาหารครัวเล็ก ๆ ผู้ค้าริมถนนผู้ขายที่ไม่มีใบอนุญาต เจ้าของ ฯลฯ และความชั่วร้าย (ย่อย) นเรศวร - รู้จักกันดีในนามเขาผู้ซึ่งไม่ควรถูกปฏิเสธ - บ่นว่าฉันแสดงข้อความค้นหามากเกินไปในระยะ GetDietaryInformation
หมายเหตุ : ฉันทราบว่าในหลาย ๆ มุมมองนี่ไม่ใช่ปัญหาเลย (ไม่สนใจปัญหาประสิทธิภาพที่เป็นไปได้ ฯลฯ ) สิ่งที่เกิดขึ้นคือตัวชี้วัดเฉพาะไม่มีความสุขและมีเหตุผลสำหรับสิ่งนั้น
สิ่งที่ฉันคิดว่าฉันสามารถทำได้
นอกเหนือจากข้อแรกตัวเลือกทั้งหมดเหล่านี้สามารถทำได้และฉันคิดว่าสามารถป้องกันได้
protected
ฉันได้ยืนยันว่าผมสามารถส่อเสียดและประกาศครึ่งหนึ่งวิธีของฉัน แต่ฉันจะใช้ประโยชน์จากจุดอ่อนในกระบวนการทดสอบและนอกเหนือจากการพิสูจน์ตัวเองเมื่อถูกจับฉันไม่ชอบสิ่งนี้ นอกจากนี้ยังเป็นมาตรการชั่วคราว เกิดอะไรขึ้นถ้าจำนวนของการดำเนินการที่ต้องการเป็นสองเท่า? ไม่แน่ แต่แล้วจะเป็นอย่างไร- ฉันสามารถแยกเฟสนี้โดยพลการเป็น AnnealedObjectAlpha, AnnealedObjectBravo และ AnnealedObjectCharlie และมีหนึ่งในสามของการดำเนินการที่ดำเนินการในแต่ละขั้นตอน ฉันอยู่ภายใต้ความประทับใจที่จริง ๆ แล้วเพิ่มความซับซ้อน (คลาสเพิ่มเติม N-1) โดยไม่มีประโยชน์ยกเว้นการผ่านการทดสอบ แน่นอนฉันสามารถถือได้ว่า CarWithFrontSeatsInstalled และ CarWithAllSeatsInstalled เป็นขั้นตอนต่อเนื่องเชิงตรรกะ ความเสี่ยงของวิธีการ Bravo ที่ Alpha จำเป็นต้องใช้ในภายหลังนั้นมีขนาดเล็กและเล็กลงถ้าฉันเล่นได้ดี แต่ยังคง.
- ฉันสามารถมัดการทำงานที่แตกต่างกันคล้ายกันจากระยะไกลในหนึ่งเดียว
performAllSeatsInstallation()
. นี่เป็นเพียงมาตรการชั่วคราวและเพิ่มความซับซ้อนของการดำเนินการเดียว หากฉันต้องการดำเนินการ A และ B ตามลำดับที่แตกต่างกันและฉันได้บรรจุไว้ใน E = (A + C) และ F (B + D) ฉันจะต้องแยก E และ F และสลับรหัสรอบ ๆ . - ฉันสามารถใช้ฟังก์ชั่นแลมบ์ดาได้หลายอย่างและเลี่ยงขั้นตอนการตรวจสอบโดยสิ้นเชิง แต่ฉันพบว่ามันเป็น clunky อย่างไรก็ตามนี่เป็นทางเลือกที่ดีที่สุดจนถึงปัจจุบัน มันจะกำจัดการสะท้อนกลับ ปัญหาสองอย่างที่ฉันมีคือฉันอาจจะถูกขอให้เขียนวัตถุวิธีการทั้งหมดไม่เพียง แต่สมมุติ
CarWithEngineInstalled
และในขณะที่จะรักษาความปลอดภัยงานที่ดีมากมันไม่ได้ดึงดูดมาก และตัวตรวจสอบรหัสครอบคลุมมีปัญหากับ lambdas (ซึ่งแก้ไขได้ แต่ยังคงอยู่ )
ดังนั้น...
- คุณคิดว่าตัวเลือกที่ดีที่สุดของฉันคืออะไร?
- มีวิธีที่ดีกว่าที่ฉันไม่ได้พิจารณาหรือไม่? ( บางทีฉันควรจะมาทำความสะอาดและถามว่ามันคืออะไร? )
- การออกแบบนี้มีข้อบกพร่องอย่างสิ้นหวังและฉันควรยอมรับความพ่ายแพ้และคลอง - สถาปัตยกรรมนี้โดยสิ้นเชิง? ไม่ดีสำหรับอาชีพการงานของฉัน แต่การเขียนโค้ดที่ออกแบบมาไม่ดีจะดีกว่าในระยะยาวหรือไม่
- ตัวเลือกปัจจุบันของฉันคือทางเลือกเดียวหรือไม่และฉันต้องต่อสู้เพื่อให้ได้การวัดคุณภาพที่ดีขึ้น (และ / หรือเครื่องมือ) สำหรับตัวเลือกสุดท้ายนี้ฉันจะต้องอ้างอิง ... ฉันไม่สามารถเพียงแค่คลื่นมือของฉันที่ @PHB ในขณะที่บ่นเหล่านี้ไม่ได้ชี้วัดที่คุณกำลังมองหา ไม่ว่าฉันจะอยากได้เท่าไหร่