เพื่อนร่วมงานของฉันชอบพูดว่า "การบันทึก / การแคช / ฯลฯ เป็นข้อกังวลข้าม" จากนั้นดำเนินการใช้ซิงเกิลที่เกี่ยวข้องทุกที่ พวกเขารัก IoC และ DI
มันเป็นข้อแก้ตัวที่ถูกต้องหรือไม่ที่จะทำลายหลักการของ SOLI D ?
เพื่อนร่วมงานของฉันชอบพูดว่า "การบันทึก / การแคช / ฯลฯ เป็นข้อกังวลข้าม" จากนั้นดำเนินการใช้ซิงเกิลที่เกี่ยวข้องทุกที่ พวกเขารัก IoC และ DI
มันเป็นข้อแก้ตัวที่ถูกต้องหรือไม่ที่จะทำลายหลักการของ SOLI D ?
คำตอบ:
เลขที่
SOLID มีอยู่เป็นแนวทางในการบัญชีสำหรับการเปลี่ยนแปลงที่หลีกเลี่ยงไม่ได้ คุณจริงๆไม่เคยจะเปลี่ยนเข้าสู่ระบบห้องสมุดหรือเป้าหมายของคุณหรือกรองหรือการจัดรูปแบบหรือ ... ? คุณจริงๆไม่ได้ไปเปลี่ยนห้องสมุดของคุณแคชหรือเป้าหมายหรือกลยุทธ์หรือการกำหนดขอบเขตหรือ ... ?
แน่นอนคุณเป็น. ที่อย่างน้อยที่สุดคุณจะต้องการที่จะเยาะเย้ยสิ่งเหล่านี้ในทางที่มีเหตุผลที่จะแยกพวกเขาสำหรับการทดสอบ และถ้าคุณต้องการแยกพวกมันสำหรับการทดสอบคุณอาจจะพบกับเหตุผลทางธุรกิจที่คุณต้องการแยกพวกมันออกเพื่อเหตุผลในชีวิตจริง
และจากนั้นคุณจะได้รับข้อโต้แย้งว่าคนตัดไม้ตัวเองจะจัดการการเปลี่ยนแปลง "โอ้ถ้าเป้าหมาย / การกรอง / การจัดรูปแบบ / การเปลี่ยนแปลงกลยุทธ์แล้วเราจะเปลี่ยนการตั้งค่า!" นั่นคือขยะ ตอนนี้ไม่เพียง แต่คุณมี God Object ที่จัดการสิ่งเหล่านี้ทั้งหมดคุณกำลังเขียนโค้ดของคุณใน XML (หรือคล้ายกัน) ที่คุณไม่ได้รับการวิเคราะห์แบบคงที่คุณไม่ได้รับข้อผิดพลาดในการรวบรวมเวลาและคุณไม่ต้อง ไม่ได้รับการทดสอบหน่วยที่มีประสิทธิภาพจริงๆ
มีกรณีละเมิดแนวทางปฏิบัติของ SOLID หรือไม่? อย่างแน่นอน บางครั้งสิ่งต่าง ๆจะไม่เปลี่ยนแปลง (โดยไม่ต้องมีการเขียนใหม่ทั้งหมด) บางครั้งการละเมิด LSP เล็กน้อยเป็นวิธีที่สะอาดที่สุด บางครั้งการสร้างส่วนต่อประสานที่แยกออกมาก็ไม่มีประโยชน์อะไร
แต่การบันทึกและการแคช (และปัญหาการตัดขวางที่แพร่หลายอื่น ๆ ) ไม่ใช่กรณีเหล่านั้น พวกเขามักจะเป็นตัวอย่างที่ดีของปัญหาการมีเพศสัมพันธ์และการออกแบบที่คุณได้รับเมื่อคุณละเลยแนวทาง
String
หรือInt32
หรือแม้กระทั่งList
ออกจากโมดูลของคุณ มีเพียงขอบเขตที่สมเหตุสมผลและมีสติในการวางแผนการเปลี่ยนแปลง และนอกเหนือจากประเภท "แกนกลาง" ที่เห็นได้ชัดส่วนใหญ่การแยกแยะสิ่งที่คุณอาจเปลี่ยนไปนั้นเป็นเพียงประสบการณ์และการตัดสินอย่างแท้จริง
ใช่
นี่คือประเด็นทั้งหมดของคำว่า "ความกังวลเกี่ยวกับการตัดขวาง" - หมายถึงบางสิ่งที่ไม่เหมาะสมอย่างเป็นระเบียบในหลักการของโซลิด
นี่คือที่ที่อุดมการณ์พบกับความเป็นจริง
ผู้คนกึ่งใหม่สู่ SOLID และการตัดขวางมักจะพบกับความท้าทายทางจิตนี้ ไม่เป็นไรไม่เป็นไร พยายามใส่ทุกอย่างในแง่ของ SOLID แต่มีบางสถานที่เช่นการบันทึกและการแคชที่ SOLID ไม่สมเหตุสมผล การตัดขวางเป็นพี่ชายของ SOLID พวกเขาไปจับมือกัน
HttpContextBase
(ซึ่งถูกนำมาใช้ด้วยเหตุผลนี้) ฉันรู้แน่นอนว่าความจริงของฉันจะเปรี้ยวจริงๆถ้าไม่มีคลาสนี้
สำหรับการบันทึกฉันคิดว่ามันเป็น การบันทึกนั้นแพร่หลายและโดยทั่วไปไม่เกี่ยวข้องกับการทำงานของบริการ เป็นเรื่องปกติและเป็นที่เข้าใจกันดีในการใช้รูปแบบการบันทึกเฟรมเดี่ยว ถ้าคุณทำไม่ได้คุณกำลังสร้างและฉีดคนตัดไม้ทุกที่และคุณไม่ต้องการ
ปัญหาหนึ่งจากด้านบนคือมีคนพูดว่า'แต่ฉันจะทดสอบการบันทึกได้อย่างไร' . ความคิดของฉันคือโดยปกติฉันไม่ได้ทดสอบการบันทึกนอกเหนือจากการยืนยันว่าฉันสามารถอ่านไฟล์บันทึกและเข้าใจพวกเขาได้ เมื่อฉันเห็นการทดสอบการบันทึกมักจะเป็นเพราะมีคนต้องการยืนยันว่าชั้นเรียนได้ทำบางสิ่งบางอย่างจริง ๆแล้วพวกเขากำลังใช้ข้อความบันทึกเพื่อรับข้อเสนอแนะนั้น ฉันอยากจะลงทะเบียนผู้ฟัง / ผู้สังเกตการณ์บางคนในชั้นเรียนนั้นและยืนยันในแบบทดสอบของฉันที่เรียกว่า จากนั้นคุณสามารถวางบันทึกเหตุการณ์ของคุณภายในผู้สังเกตการณ์นั้น
ฉันคิดว่าการแคชเป็นสถานการณ์ที่แตกต่างอย่างสิ้นเชิงอย่างไรก็ตาม
2 เซ็นต์ของฉัน ...
ใช่และไม่.
คุณไม่ควรจริงๆละเมิดหลักการที่คุณนำมาใช้; แต่หลักการของคุณควรจะเหมาะสมและนำมาใช้ในการบริการเพื่อเป้าหมายที่สูงขึ้น ดังนั้นด้วยความเข้าใจที่ถูกต้องปรับอากาศบางชัดเจนละเมิดอาจจะไม่เกิดขึ้นจริงการละเมิดของ "จิตวิญญาณ" หรือ "ร่างของหลักการโดยรวม."
โดยเฉพาะอย่างยิ่งหลักการของ SOLID นอกเหนือจากการกำหนดให้มีความแตกต่างกันนิดหน่อยในที่สุดก็ยอมจำนนต่อเป้าหมายของ "การส่งมอบซอฟต์แวร์ที่ทำงานได้ ดังนั้นการยึดมั่นในหลักการใด ๆ ของ SOLID คือการเอาชนะตนเองและขัดแย้งตัวเองเมื่อทำเช่นนั้นจะขัดแย้งกับเป้าหมายของ SOLID และที่นี่ผมมักจะทราบว่าการส่งมอบการปั้นการบำรุงรักษา
แล้วDในโซลิดล่ะ? มันช่วยให้การบำรุงรักษาเพิ่มขึ้นด้วยการทำให้โมดูลที่ใช้ซ้ำได้ของคุณค่อนข้างไม่เชื่อในบริบทของมัน และเราสามารถกำหนด "โมดูลที่ใช้ซ้ำได้" เป็น "ชุดของรหัสที่คุณวางแผนที่จะใช้ในบริบทที่แตกต่างกัน" และที่ใช้กับฟังก์ชั่นเดียว, คลาส, ชุดของคลาสและโปรแกรม
และใช่แล้วการเปลี่ยนการใช้งานตัวบันทึกอาจทำให้โมดูลของคุณกลายเป็น "บริบทที่แตกต่าง"
ดังนั้นฉันขอเสนอข้อแม้ใหญ่สองข้อของฉัน :
ประการแรก: การ วาดเส้นรอบ ๆ บล็อกของรหัสที่ประกอบด้วย "โมดูลที่ใช้ซ้ำได้" เป็นเรื่องของการตัดสินอย่างมืออาชีพ และการตัดสินใจของคุณนั้น จำกัด อยู่ที่ประสบการณ์ของคุณ
หากคุณไม่ได้ในขณะนี้วางแผนที่จะใช้โมดูลในบริบทอื่นก็คืออาจจะตกลงให้มันขึ้นอยู่กับมันอย่างช่วยไม่ได้ ข้อแม้ถึงข้อแม้: แผนการของคุณอาจผิด - แต่ก็ไม่เป็นไร ยิ่งคุณเขียนโมดูลหลังจากโมดูลนานเท่าไรคุณจะยิ่งเข้าใจได้ง่ายขึ้นและแม่นยำมากขึ้นว่า "ฉันจะต้องใช้มันอีกซักวันหนึ่ง" แต่คุณอาจจะไม่สามารถพูดย้อนหลังได้ว่า "ฉันทำให้เป็นโมดูลและแยกชิ้นส่วนทุกอย่างออกมามากที่สุดแต่ก็ไม่เกิน "
หากคุณรู้สึกผิดเกี่ยวกับข้อผิดพลาดของคุณในการตัดสินโปรดไปที่คำสารภาพและดำเนินการต่อ ...
ประการที่สอง: การกลับการควบคุมไม่เท่ากับการพึ่งพาการฉีด
นี่คือความจริงโดยเฉพาะอย่างยิ่งเมื่อคุณเริ่มฉีดอ้างอิง nauseam การพึ่งพาการฉีดเป็นกลยุทธ์ที่มีประโยชน์สำหรับกลยุทธ์ IoC ที่ครอบคลุม แต่ฉันขอยืนยันว่า DI นั้นมีประสิทธิภาพน้อยกว่ากลยุทธ์อื่น ๆ เช่นการใช้อินเทอร์เฟซและอะแดปเตอร์จุดสัมผัสเพียงจุดเดียวกับบริบทจากภายในโมดูล
และลองจดจ่อกับสิ่งนี้เป็นครั้งที่สอง เพราะแม้ว่าคุณจะฉีดLogger
โฆษณาคลื่นไส้คุณต้องเขียนโค้ดกับLogger
อินเทอร์เฟซ คุณไม่สามารถเริ่มต้นใช้งานใหม่Logger
จากผู้จำหน่ายรายอื่นที่รับพารามิเตอร์ตามลำดับที่แตกต่างกัน ความสามารถนั้นมาจากการเข้ารหัสภายในโมดูลเทียบกับอินเทอร์เฟซที่มีอยู่ภายในโมดูลและมี submodule (อะแดปเตอร์) เดียวในนั้นเพื่อจัดการการพึ่งพา
และถ้าคุณกำลังเขียนโค้ดกับอแด็ปเตอร์ไม่ว่าLogger
จะถูกส่งไปยังอแด็ปเตอร์นั้นหรือถูกค้นพบโดยอแด็ปเตอร์นั้นค่อนข้างไม่สำคัญกับเป้าหมายการบำรุงรักษาโดยรวม และที่สำคัญกว่านั้นคือถ้าคุณมีอะแดปเตอร์ระดับโมดูลก็อาจจะเป็นเรื่องเหลวไหลที่จะฉีดเข้าไปในอะไรก็ได้ มันเขียนสำหรับโมดูล
tl; dr - หยุดยุ่งเกี่ยวกับหลักการโดยไม่คำนึงถึงสาเหตุที่คุณใช้หลักการ และในทางปฏิบัติมากขึ้นเพียงสร้างAdapter
สำหรับแต่ละโมดูล ใช้วิจารณญาณของคุณเมื่อตัดสินใจว่าคุณจะวาดขอบเขตที่ "โมดูล" Adapter
จากภายในแต่ละโมดูลไปข้างหน้าและการอ้างอิงโดยตรงกับ และแน่นอนว่าให้ฉีดlogger ที่แท้จริงลงในAdapter
- แต่ไม่ใช่ทุก ๆ สิ่งที่อาจจำเป็นต้องใช้
แนวคิดที่ว่าการบันทึกควรจะถูกนำมาใช้เป็นซิงเกิลเป็นหนึ่งในการโกหกที่ได้รับการบอกกล่าวบ่อยครั้งที่มันได้รับแรงฉุด
นานเท่าที่ระบบปฏิบัติการที่ทันสมัยได้รับเกี่ยวกับเรื่องนี้ได้รับการยอมรับว่าคุณอาจต้องการที่จะเข้าสู่ระบบไปยังสถานที่หลาย ๆ ขึ้นอยู่กับธรรมชาติของการส่งออก
ผู้ออกแบบระบบควรตั้งคำถามถึงประสิทธิภาพของการแก้ปัญหาในอดีตอย่างต่อเนื่องก่อนที่จะสุ่มสี่สุ่มห้า หากพวกเขาไม่ได้ดำเนินการอย่างขยันขันแข็งเช่นนั้นพวกเขาจะไม่ทำงานของพวกเขา
การบันทึกอย่างแท้จริงเป็นกรณีพิเศษ
@Telastyn เขียน:
คุณจะไม่เปลี่ยนไลบรารีการบันทึกหรือเป้าหมายหรือการกรองหรือการจัดรูปแบบหรือ ... หรือไม่?
หากคุณคาดหวังว่าคุณอาจต้องเปลี่ยนไลบรารีการบันทึกของคุณคุณควรใช้ส่วนหน้า เช่น SLF4J หากคุณอยู่ในโลก Java
สำหรับส่วนที่เหลือไลบรารีการบันทึกที่เหมาะสมจะดูแลการเปลี่ยนตำแหน่งการบันทึกไปยังสิ่งที่เหตุการณ์ถูกกรองวิธีการจัดรูปแบบบันทึกเหตุการณ์โดยใช้ไฟล์การกำหนดค่าตัวบันทึกและ (ถ้าจำเป็น) คลาสปลั๊กอินที่กำหนดเอง มีทางเลือกนอกชั้นวางจำนวนมาก
ในระยะสั้นปัญหาเหล่านี้ได้รับการแก้ไข ... สำหรับการบันทึก ... และด้วยเหตุนี้จึงไม่จำเป็นต้องใช้การฉีดพึ่งพาเพื่อแก้ปัญหาเหล่านั้น
กรณีเดียวที่ DI อาจมีประโยชน์ (เหนือวิธีการบันทึกมาตรฐาน) คือถ้าคุณต้องการบันทึกการใช้งานแอปพลิเคชันของคุณเพื่อทดสอบหน่วย แต่ผมสงสัยว่านักพัฒนาส่วนใหญ่จะบอกว่าการเข้าสู่ระบบไม่ได้เป็นส่วนหนึ่งของการทำงานการเรียนและไม่ใช่สิ่งที่ตอบสนองความต้องการที่จะทดสอบ
@Telastyn เขียน:
จากนั้นคุณจะได้รับข้อโต้แย้งว่าคนตัดไม้จะจัดการกับการเปลี่ยนแปลง "โอ้ถ้าเป้าหมาย / การกรอง / การจัดรูปแบบ / การเปลี่ยนแปลงกลยุทธ์แล้วเราจะเปลี่ยนการตั้งค่า!" นั่นคือขยะ ตอนนี้ไม่เพียง แต่คุณมี God Object ที่จัดการสิ่งเหล่านี้ทั้งหมดคุณกำลังเขียนโค้ดของคุณใน XML (หรือคล้ายกัน) ที่คุณไม่ได้รับการวิเคราะห์แบบคงที่คุณไม่ได้รับข้อผิดพลาดในการรวบรวมเวลาและคุณไม่ต้อง ไม่ได้รับการทดสอบหน่วยที่มีประสิทธิภาพจริงๆ
ฉันกลัวว่ามันเป็นทฤษฎีที่น่าเชื่อถือมาก ในทางปฏิบัติผู้พัฒนาระบบและผู้รวมระบบส่วนใหญ่ชอบข้อเท็จจริงที่ว่าคุณสามารถกำหนดค่าการบันทึกผ่านไฟล์กำหนดค่า และพวกเขาชอบความจริงที่ว่าพวกเขาไม่ได้คาดหวังให้ทดสอบการบันทึกของโมดูล
แน่นอนว่าหากคุณบันทึกการกำหนดค่าไว้คุณก็จะพบปัญหา แต่สิ่งเหล่านี้จะแสดงให้เห็นว่าแอปพลิเคชันล้มเหลวระหว่างการเริ่มต้นระบบหรือการบันทึกน้อยเกินไป / มากเกินไป 1) ปัญหาเหล่านี้แก้ไขได้ง่าย ๆ โดยแก้ไขข้อผิดพลาดในไฟล์ปรับแต่ง 2) ทางเลือกคือการสร้าง / วิเคราะห์ / ทดสอบ / ปรับใช้รอบแต่ละครั้งที่คุณทำการเปลี่ยนแปลงระดับการเข้าสู่ระบบ ไม่เป็นที่ยอมรับ
ใช่ และ ไม่ !
ใช่: ฉันคิดว่ามันมีเหตุผลที่ระบบย่อยต่าง ๆ (หรือ semantic layer หรือ library หรือพัฒนาการอื่น ๆ ของ modular bundling) แต่ละคนยอมรับ (เหมือนกันหรือ) logger ที่แตกต่างกันในระหว่างการเริ่มต้นแทนที่จะเป็นระบบย่อยทั้งหมดที่อาศัย singletonมากกว่าระบบย่อยทั้งหมดอาศัยเดี่ยวทั่วไปเดียวกันที่ใช้ร่วมกัน
อย่างไรก็ตาม
ไม่: ในขณะเดียวกันก็ไม่มีเหตุผลที่จะทำการบันทึกพารามิเตอร์ในทุก ๆ วัตถุ (โดยวิธีการสร้างหรือวิธีการตัวอย่าง) เพื่อหลีกเลี่ยงการขยายตัวที่ไม่จำเป็นและไม่มีจุดหมายองค์กรขนาดเล็กควรใช้ตัวบันทึกคนเดียวของบริบทที่ล้อมรอบ
นี่คือเหตุผลหนึ่งในหมู่คนอื่น ๆ ที่จะคิดว่าเป็นโมดูลในระดับ: วิธีการที่จะถูกรวมเข้าไปในชั้นเรียนในขณะที่เรียนรวมอยู่ในระบบย่อยและ / หรือชั้นความหมาย ชุดข้อมูลขนาดใหญ่เหล่านี้เป็นเครื่องมือที่มีค่าในการทำให้เป็นนามธรรม เราควรให้การพิจารณาที่แตกต่างกันภายในขอบเขตแบบแยกส่วนมากกว่าเมื่อข้ามมัน
ก่อนอื่นมันเริ่มต้นด้วย singleton cache ที่แข็งแกร่งสิ่งต่อไปที่คุณเห็นคือ singletons ที่แข็งแกร่งสำหรับเลเยอร์ฐานข้อมูลที่แนะนำสถานะโกลบอล API ที่ไม่ใช่คำอธิบายของ class
es และรหัสที่ไม่สามารถพิสูจน์ได้
หากคุณตัดสินใจที่จะไม่ใช้ซิงเกิลตันสำหรับฐานข้อมูลอาจไม่ใช่ความคิดที่ดีที่จะมีซิงเกิลตันสำหรับแคชเพราะมันแสดงแนวคิดที่คล้ายกันมากคือการจัดเก็บข้อมูลโดยใช้กลไกที่ต่างกันเท่านั้น
การใช้ซิงเกิลตันในคลาสจะเปลี่ยนคลาสที่มีจำนวนการพึ่งพาเฉพาะกับคลาสที่มีตามทฤษฎีจำนวนที่ไม่มีที่สิ้นสุดของพวกเขาเพราะคุณไม่เคยรู้ว่าสิ่งใดถูกซ่อนอยู่เบื้องหลังวิธีการคงที่
ในทศวรรษที่ผ่านมาฉันใช้เวลาเขียนโปรแกรมมีเพียงกรณีเดียวที่ฉันเห็นความพยายามในการเปลี่ยนตรรกะการบันทึก (ซึ่งถูกเขียนเป็นซิงเกิล) ดังนั้นถึงแม้ว่าฉันจะชอบการฉีดพึ่งพา แต่การบันทึกไม่ได้เป็นเรื่องใหญ่มากนัก ในทางกลับกันแคชฉันมักจะทำให้เป็นที่พึ่ง
ใช่และไม่ใช่ แต่ส่วนใหญ่ไม่ใช่
ฉันคิดว่าบทสนทนาส่วนใหญ่จะอิงจากอินสแตนซ์แบบคงที่เทียบกับการฉีด ไม่มีใครเสนอว่าการบันทึกทำลาย SRP ที่ฉันคิดเอาไว้? ส่วนใหญ่เรากำลังพูดถึง "หลักการการพึ่งพาการพึ่งพาอาศัยกัน" Tbh ฉันส่วนใหญ่เห็นด้วยกับไม่มีคำตอบของ Telastyn
เมื่อใดที่จะใช้สถิตยศาสตร์? เพราะเห็นได้ชัดว่าบางครั้งมันก็โอเค จุดตอบรับใช่ของผลประโยชน์ของสิ่งที่เป็นนามธรรมและคำตอบ "ไม่" ชี้ให้เห็นว่าเป็นสิ่งที่คุณจ่ายไป หนึ่งในเหตุผลที่งานของคุณยากคือไม่มีคำตอบเดียวที่คุณสามารถจดบันทึกและนำไปใช้กับทุกสถานการณ์ได้
ใช้:
Convert.ToInt32("1")
ฉันชอบสิ่งนี้:
private readonly IConverter _converter;
public MyClass(IConverter converter)
{
Guard.NotNull(converter)
_converter = conveter
}
....
var foo = _converter.ToInt32("1");
ทำไม? ฉันยอมรับว่าฉันจะต้อง refactor รหัสถ้าฉันต้องการความยืดหยุ่นในการแลกเปลี่ยนรหัสการแปลง ฉันยอมรับว่าฉันจะไม่สามารถเยาะเย้ยเรื่องนี้ได้ ฉันเชื่อว่าความเรียบง่ายและความทนทานนั้นคุ้มค่ากับการค้าขายนี้
เมื่อมองไปที่ปลายอีกด้านของสเปกตรัมถ้าIConverter
เป็นSqlConnection
ผมจะต้องตกใจเมื่อเห็นว่าเป็นการโทรคงที่ สาเหตุที่เห็นได้ชัดคือ faily ฉันจะชี้ให้เห็นว่าSQLConnection
สามารถ "cross-cutting" ในการปรบมือดังนั้นฉันจะไม่ใช้คำที่แน่นอนเหล่านั้น
คือการเข้าสู่ระบบมากขึ้นเช่นSQLConnection
หรือConvert.ToInt32
? ฉันจะพูดมากขึ้นเช่น 'SQLConnection`
คุณควรจะเยาะเย้ยเข้าสู่ระบบ มันพูดกับโลกภายนอก เมื่อเขียนวิธีการใช้Convert.ToIn32
ฉันใช้มันเป็นเครื่องมือในการคำนวณผลลัพธ์อื่น ๆ ที่ทดสอบได้แยกต่างหากของชั้นเรียน ฉันไม่ต้องการตรวจสอบConvert
ถูกเรียกอย่างถูกต้องเมื่อตรวจสอบว่า "1" + "2" == "3" การบันทึกแตกต่างกันมันเป็นเอาต์พุตแบบอิสระทั้งหมดของคลาส ฉันถือว่าเป็นผลผลิตที่มีคุณค่าต่อคุณทีมสนับสนุนและธุรกิจ ชั้นเรียนของคุณไม่ทำงานหากการบันทึกไม่ถูกต้องดังนั้นการทดสอบหน่วยไม่ควรผ่าน คุณควรทดสอบสิ่งที่ชั้นเรียนของคุณบันทึก ฉันคิดว่านี่เป็นอาร์กิวเมนต์นักฆ่าฉันหยุดที่นี่ได้จริงๆ
ฉันก็คิดว่ามันเป็นสิ่งที่ค่อนข้างจะเปลี่ยนแปลง การบันทึกที่ดีไม่เพียง แต่พิมพ์สตริง แต่เป็นสิ่งที่แอปพลิเคชันของคุณกำลังทำอยู่ (ฉันเป็นแฟนตัวยงของการบันทึกตามเหตุการณ์) ฉันเห็นการบันทึกพื้นฐานกลายเป็นการรายงาน UIs ที่ค่อนข้างซับซ้อน เห็นได้ชัดว่ามันง่ายมากที่จะมุ่งหน้าไปในทิศทางนี้ถ้าการบันทึกของคุณมีลักษณะ_logger.Log(new ApplicationStartingEvent())
และไม่เหมือนLogger.Log("Application has started")
กัน อาจมีคนแย้งว่านี่คือการสร้างสินค้าคงคลังสำหรับอนาคตที่อาจไม่เคยเกิดขึ้นนี่คือการตัดสินและฉันคิดว่ามันคุ้มค่า
ในความเป็นจริงในโครงการส่วนตัวของฉันฉันสร้าง UI ที่ไม่ได้เข้าสู่ระบบโดยใช้_logger
เพื่อหาว่าแอปพลิเคชันทำอะไร นี่หมายความว่าฉันไม่จำเป็นต้องเขียนโค้ดเพื่อค้นหาว่าแอปพลิเคชันทำอะไรและฉันก็จบลงด้วยการบันทึกที่มั่นคง ฉันรู้สึกเหมือนว่าทัศนคติต่อการบันทึกของฉันนั้นง่ายและไม่เปลี่ยนแปลงความคิดนั้นจะไม่เกิดขึ้นกับฉัน
ดังนั้นฉันเห็นด้วยกับ Telastyn สำหรับกรณีการบันทึก
Semantic Logging Application Block
และมองขึ้นไปบันทึกเหตุการณ์คุณจะพบ อย่าใช้มันเช่นเดียวกับรหัสส่วนใหญ่ที่สร้างขึ้นโดยทีม "ลวดลายและการปฏิบัติ" ของ MS โดยประชดประชันมันเป็นปฏิปักษ์
ความกังวลเกี่ยวกับการตัดครั้งแรกไม่ใช่สิ่งก่อสร้างที่สำคัญและไม่ควรถือว่าเป็นการพึ่งพาในระบบ ระบบควรทำงานถ้าเช่น Logger ไม่ได้เริ่มต้นหรือแคชไม่ทำงาน คุณจะทำให้ระบบมีความกลมกลืนและกันน้อยลงอย่างไร? นั่นคือสิ่งที่ SOLID เข้ามาในภาพในการออกแบบระบบ OO
การรักษาวัตถุอย่างเดียวไม่ได้เกี่ยวข้องกับ SOLID นั่นคือวัฏจักรชีวิตของคุณว่าคุณต้องการให้วัตถุอยู่ในความทรงจำนานแค่ไหน
คลาสที่ต้องการการพึ่งพาเพื่อเตรียมใช้งานไม่ควรทราบว่าอินสแตนซ์ของคลาสที่ให้มานั้นเป็นแบบซิงเกิลหรือแบบชั่วคราว แต่ tldr; ถ้าคุณกำลังเขียน Logger.Instance.Log () ในทุก ๆ เมธอดหรือคลาสมันเป็นโค้ดที่มีปัญหา (code ดมกลิ่น / คลัปแข็ง) เป็นระเบียบมาก นี่คือช่วงเวลาที่คนเริ่มเหยียดหยามโซลิด และผู้พัฒนาเพื่อนอย่าง OP เริ่มถามคำถามของแท้เช่นนี้
ฉันได้แก้ไขปัญหานี้โดยใช้การผสมผสานระหว่างการสืบทอดและลักษณะ (เรียกอีกอย่างว่ามิกซ์อินในบางภาษา) ลักษณะพิเศษมีประโยชน์อย่างยิ่งสำหรับการแก้ปัญหาการตัดขวางแบบนี้ ปกติแล้วจะเป็นฟีเจอร์ภาษา แต่ฉันคิดว่าคำตอบที่แท้จริงคือมันขึ้นอยู่กับฟีเจอร์ของภาษา