มีสองวิธีในการใช้คลาสฐานที่เป็นนามธรรม
คุณมีความเชี่ยวชาญในวัตถุนามธรรมของคุณ แต่ลูกค้าทั้งหมดจะใช้คลาสที่ได้รับผ่านส่วนต่อประสานพื้นฐาน
คุณกำลังใช้คลาสพื้นฐานที่เป็นนามธรรมเพื่อแยกแยะความซ้ำซ้อนภายในวัตถุในการออกแบบของคุณและไคลเอนต์ใช้การใช้งานที่เป็นรูปธรรมผ่านอินเทอร์เฟซของพวกเขาเอง!
โซลูชันสำหรับ 1 - รูปแบบกลยุทธ์
หากคุณมีสถานการณ์แรกแสดงว่าคุณมีอินเทอร์เฟซที่กำหนดโดยวิธีเสมือนในคลาสนามธรรมที่คลาสที่ได้รับของคุณกำลังใช้งานอยู่
คุณควรพิจารณาให้เป็นอินเทอร์เฟซจริงเปลี่ยนคลาสนามธรรมของคุณให้เป็นรูปธรรมและใช้อินสแตนซ์ของอินเทอร์เฟซนี้ในตัวสร้าง คลาสที่ได้รับของคุณจะกลายเป็นการใช้งานอินเทอร์เฟซใหม่นี้
ซึ่งหมายความว่าตอนนี้คุณสามารถทดสอบคลาสนามธรรมของคุณก่อนหน้านี้โดยใช้อินสแตนซ์จำลองของอินเทอร์เฟซใหม่และแต่ละการใช้งานใหม่ผ่านอินเทอร์เฟซสาธารณะในขณะนี้ ทุกอย่างง่ายและทดสอบได้
โซลูชันสำหรับ 2
หากคุณมีสถานการณ์ที่สองคลาสนามธรรมของคุณจะทำงานเป็นคลาสผู้ช่วย
ดูฟังก์ชันการทำงานที่มีอยู่ ดูว่าสามารถผลักสิ่งใดสิ่งหนึ่งลงบนวัตถุที่ถูกจัดการเพื่อลดการทำซ้ำนี้ให้น้อยที่สุดได้หรือไม่ หากคุณยังมีอะไรเหลือให้ดูที่การสร้างคลาสผู้ช่วยที่การปฏิบัติที่เป็นรูปธรรมของคุณต้องใช้ตัวสร้างและลบคลาสพื้นฐาน
สิ่งนี้นำไปสู่คลาสที่เป็นรูปธรรมที่ง่ายและทดสอบได้ง่าย
ในฐานะที่เป็นกฎ
สนับสนุนเครือข่ายที่ซับซ้อนของวัตถุอย่างง่ายผ่านเครือข่ายที่ซับซ้อนของวัตถุที่ซับซ้อน
กุญแจสำคัญในการทดสอบรหัสที่ขยายได้คือบล็อคขนาดเล็กและการเดินสายอิสระ
อัปเดต: จะจัดการส่วนผสมของทั้งสองได้อย่างไร
เป็นไปได้ที่จะมีคลาสฐานแสดงบทบาทเหล่านี้ทั้งสอง ... เช่น: มีส่วนต่อประสานสาธารณะและมีวิธีการป้องกันผู้ช่วยเหลือ หากเป็นกรณีนี้คุณสามารถแยกวิธีการช่วยเหลือออกเป็นหนึ่งคลาส (สถานการณ์ 2) และแปลงแผนผังการสืบทอดเป็นรูปแบบกลยุทธ์
หากคุณพบว่าคุณมีวิธีการบางอย่างที่คลาสพื้นฐานของคุณนำไปใช้โดยตรงและวิธีอื่นเป็นเสมือนคุณสามารถแปลงแผนภูมิการสืบทอดเป็นรูปแบบกลยุทธ์ได้ แต่ฉันก็จะใช้มันเป็นตัวบ่งชี้ที่ดีว่า ต้องการ refactoring
อัปเดต 2: คลาสนามธรรมเป็นสเต็ปปิ้ง (2014/06/12)
ฉันมีสถานการณ์เมื่อวันก่อนที่ฉันใช้นามธรรมดังนั้นฉันต้องการสำรวจว่าทำไม
เรามีรูปแบบมาตรฐานสำหรับไฟล์กำหนดค่าของเรา เครื่องมือนี้มีไฟล์กำหนดค่า 3 ไฟล์ทั้งหมดในรูปแบบนั้น ฉันต้องการคลาสที่มีการพิมพ์อย่างมากสำหรับแต่ละไฟล์การตั้งค่าดังนั้นผ่านการฉีดแบบพึ่งพาคลาสสามารถขอการตั้งค่าที่มันสนใจ
ฉันนำสิ่งนี้ไปใช้โดยให้คลาสพื้นฐานเป็นนามธรรมที่รู้วิธีแยกวิเคราะห์รูปแบบไฟล์การตั้งค่าและคลาสที่ได้รับซึ่งเปิดเผยวิธีการเดียวกัน แต่ห่อหุ้มตำแหน่งของไฟล์การตั้งค่า
ฉันสามารถเขียน "SettingsFileParser" ที่มีคลาส 3 ห่อแล้วมอบหมายผ่านไปยังคลาสพื้นฐานเพื่อเปิดเผยวิธีการเข้าถึงข้อมูล ผมเลือกที่จะไม่ทำเช่นนี้เลยที่มันจะนำไปสู่ 3 ชั้นเรียนมากับคณะผู้แทนรหัสในพวกเขามากกว่าสิ่งอื่นใด
อย่างไรก็ตาม ... เนื่องจากรหัสนี้วิวัฒนาการและผู้บริโภคของแต่ละคลาสการตั้งค่าเหล่านี้จะชัดเจนขึ้น การตั้งค่าแต่ละครั้งที่ผู้ใช้จะถามการตั้งค่าบางอย่างและแปลงพวกเขาในบางวิธี (เนื่องจากการตั้งค่าเป็นข้อความที่พวกเขาอาจห่อพวกเขาในวัตถุของการแปลงเป็นตัวเลข ฯลฯ ) เมื่อเกิดเหตุการณ์นี้ขึ้นฉันจะเริ่มแยกตรรกะนี้เป็นวิธีการจัดการข้อมูลและผลักพวกเขากลับสู่คลาสการตั้งค่าที่พิมพ์อย่างมาก สิ่งนี้จะนำไปสู่อินเทอร์เฟซระดับที่สูงขึ้นสำหรับการตั้งค่าแต่ละชุดซึ่งท้ายที่สุดก็ไม่ทราบว่ามันเกี่ยวข้องกับ 'การตั้งค่า' อีกต่อไป
ณ จุดนี้คลาสการตั้งค่าที่พิมพ์อย่างรุนแรงจะไม่ต้องการเมธอด "getter" อีกต่อไปที่จะแสดงการใช้งาน 'การตั้งค่า'
ณ จุดนี้ฉันไม่ต้องการให้ส่วนต่อสาธารณะของพวกเขารวมวิธีการเข้าถึงการตั้งค่าอีกต่อไป ดังนั้นฉันจะเปลี่ยนคลาสนี้เพื่อแค็ปซูลคลาส parser การตั้งค่าแทนที่จะได้มาจากมัน
ดังนั้น Abstract class จึงเป็นวิธีที่ฉันจะหลีกเลี่ยงรหัสมอบหมายในขณะนี้และเครื่องหมายในรหัสเพื่อเตือนให้ฉันเปลี่ยนการออกแบบในภายหลัง ฉันอาจไม่เคยไปถึงมันดังนั้นมันอาจจะมีชีวิตที่ดีในขณะที่ ... รหัสเท่านั้นที่สามารถบอกได้
ฉันพบว่าสิ่งนี้เป็นจริงกับกฎใด ๆ ... เช่น "ไม่มีวิธีการคงที่" หรือ "ไม่มีวิธีส่วนตัว" พวกมันบ่งบอกถึงกลิ่นในรหัส ... และมันก็ดี มันช่วยให้คุณมองหาสิ่งที่เป็นนามธรรมที่คุณพลาดไป ... และช่วยให้คุณสามารถมอบคุณค่าให้กับลูกค้าของคุณในเวลาเฉลี่ย
ฉันคิดว่ากฎเช่นนี้กำหนดภูมิทัศน์ที่รหัสบำรุงรักษาอยู่ในหุบเขา เมื่อคุณเพิ่มพฤติกรรมใหม่มันก็เหมือนฝนตกบนโค้ดของคุณ ตอนแรกคุณวางไว้ที่ใดก็ตามที่มันตกลงมา .. จากนั้นคุณ refactor เพื่ออนุญาตให้กองกำลังของการออกแบบที่ดีที่จะผลักดันพฤติกรรมรอบ ๆ จนกว่ามันจะจบลงในหุบเขา