คลาสบริบทในรูปแบบกลยุทธ์


10

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

ฉันตกอยู่ในความประทับใจฉันต้องการสวิตช์บางอย่างสำหรับอ่านไฟล์ประเภทต่าง ๆ แต่ไม่ต้องการแฮ็กข้อมูลและจัดการกับการรีแฟคเตอร์ใหม่ในภายหลัง (แม้ว่าแน่นอนว่ามันเกิดขึ้นเสมอว่าโค้ดสามารถรีเฟรชได้ แต่ความคิดคือ: ลอง จะฉลาดเท่าที่จะเป็นไปได้ในการออกแบบล่วงหน้า ... ):

ป้อนคำอธิบายรูปภาพที่นี่

ภาพที่นำมาจากวิกิมีเดีย

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

interface Reader {
    // read information from file and fill data list field of Client
    readFile();
}
class ExcelReader implements Reader{ /* */ }
class PdfReader implements Reader{ /* */}

class Client{
    // strategic choice
    Reader r;

    // data list field
    List<Data> data;

    // Client Constructor
    public Client(){
        if(<file ends in .xls>)
            r = new ExcelReader();
        else
            r = new PdfReader();
        r.readFile();
    }
}

ดังนั้นภาพที่ปรากฎข้างต้นคือคลาสบริบทหายไป รหัสเป็นไปตามรูปแบบกลยุทธ์หรือไม่


1
ในฐานะที่เป็นจุดสนใจ / สำคัญอีกประการหนึ่งที่ฉันอยากจะนำเสนอให้คุณทราบว่าแนวคิดของคลาสประเภทในภาษาที่ใช้งานได้คือ "เพียงแค่" รูปแบบกลยุทธ์ที่มีประเภทen.wikipedia.org/wiki/Kind_(type_theory ) ทั้งสองเป็นเพียงกลไกการดำเนินการสำหรับ ad-hoc polymorphism
AndreasScheinert

สิ่งนี้เกี่ยวข้องกับ Java 8 Project Lambda หรือไม่ บทความ Wikipedia มีความหนาแน่นเกินกว่าที่ฉันจะเข้าใจได้ในครั้งเดียว แต่ถ้าสิ่งเหล่านี้เป็นส่วนหนึ่งของพื้นหลังทางทฤษฎีสำหรับการใช้คุณลักษณะที่จะเกิดขึ้นของ Java (หรือการเขียนโปรแกรมทั่วไป) อย่างมีประสิทธิภาพฉันจะลงทุนอย่างมีความสุขมากขึ้น
panny

1
ไกลมาก แต่ฉันจะเถียงใช่จำเป็นต้องมีคลาสประเภท ภาษาโปรแกรมที่รองรับชนิดที่สูงกว่า นั่นจะเป็นกรณีของสกาล่าและแฮสเคลล์ ประเด็นของฉันที่นี่คือ (ad hoc) polymorphism มีการใช้งานที่แตกต่างกันและถ้าคุณถอยกลับคุณสามารถเรียนรู้ข้อมูลเชิงลึกเกี่ยวกับ polymorphism โดยทั่วไป
AndreasScheinert

คำตอบ:


13

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

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


5

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

แม้ว่ามันอาจจะเป็นที่ถกเถียงกันอยู่ว่าsetStrategyเป็นเรื่องส่วนตัวและการฉีดของฉันก็แค่ใช้รูปแบบดังที่แสดง


นี่หมายถึงคลาสของบริบทที่แสดงภาพสามารถถูกละไว้โดยไม่ส่งผลต่อรูปแบบได้หรือไม่? หรือกล่าวอีกนัยหนึ่งมันก็โอเคเมื่อชั้นลูกค้าของฉันเป็นชั้นบริบทที่บรรยาย?
panny

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