ทำไมฉันถึงชอบการแต่งมากกว่าการสืบทอด?


109

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

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

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

Class Shape
{
    string name;
  public:
    void getName();
    virtual void draw()=0;
}

Class Circle: public Shape
{
    void draw(/*draw circle*/);
}

57
ไม่มีเมื่อคนบอกว่าชอบองค์ประกอบพวกเขาจริงๆหมายถึงต้องการองค์ประกอบไม่ ไม่เคยเคยใช้มรดก คำถามทั้งหมดของคุณขึ้นอยู่กับหลักฐานที่ผิดพลาด ใช้การสืบทอดเมื่อเหมาะสม
Bill the Lizard

2
คุณอาจต้องการดูprogrammers.stackexchange.com/questions/65179/ …
vjones

2
ฉันเห็นด้วยกับบิลฉันเห็นการใช้การสืบทอดเป็นแนวทางปฏิบัติทั่วไปในการพัฒนา GUI
Prashant Cholachagudda

2
คุณต้องการใช้การจัดวางเพราะตารางเป็นเพียงการรวมกันของสามเหลี่ยมสองอันที่จริงฉันคิดว่ารูปทรงอื่นทั้งหมดที่ไม่ใช่วงรีเป็นเพียงการจัดเรียงของรูปสามเหลี่ยม ความแตกต่างเป็นเรื่องเกี่ยวกับภาระผูกพันตามสัญญาและ 100% ลบออกจากมรดก เมื่อสามเหลี่ยมได้รับความแปลกประหลาดเพิ่มเข้ามาเพราะใครบางคนต้องการที่จะทำให้สามารถสร้างปิรามิดได้ถ้าคุณสืบทอดจาก Triangle คุณจะได้รับทั้งหมดแม้ว่าคุณจะไม่เคยสร้างพีระมิด 3 มิติจากรูปหกเหลี่ยมของคุณ .
จิมมี่ฮอฟฟา

2
@BilltheLizard ฉันคิดว่าผู้คนมากมายที่พูดว่ามันหมายถึงการไม่เคยใช้มรดกมาก่อน แต่พวกเขาก็ผิด
immibis

คำตอบ:


51

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

แต่สิ่งที่เกี่ยวกับวัตถุที่ไม่เหมือนกัน การสร้างแบบจำลองรถยนต์และดาวเคราะห์จะแตกต่างกันมากและทั้งคู่อาจต้องการใช้พฤติกรรมของ Move ()

"But I have a feeling that when people say prefer composition, they really mean prefer a combination of composition and interface implementation."ที่จริงคุณโดยทั่วไปตอบคำถามของคุณเองเมื่อคุณกล่าวว่า พฤติกรรมทั่วไปสามารถให้ผ่านทางอินเตอร์เฟสและคอมโพสิตพฤติกรรม

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


ในทางปฏิบัติบ่อยครั้งที่ "Polymorphism ผ่านส่วนต่อประสานงาน" ปรากฏขึ้นและถือว่าเป็นเรื่องปกติ ฉันจะเดิมพันว่า polymorphism ผ่านการสืบทอดมาจากการออกแบบอย่างระมัดระวังไม่ใช่ผลของภาษา (C ++) ที่ค้นพบหลังจากสเปค
samis

1
ใครจะเรียกการเคลื่อนย้าย () บนดาวเคราะห์และรถยนต์แล้วพิจารณาเหมือนกัน! คำถามที่นี่อยู่ในบริบทที่พวกเขาควรจะย้าย? หากพวกเขาทั้งสองเป็นวัตถุสองมิติในเกม 2D ที่เรียบง่ายพวกเขาสามารถสืบทอดการเคลื่อนไหวหากพวกเขาเป็นวัตถุในการจำลองข้อมูลขนาดใหญ่มันอาจไม่สมเหตุสมผลเลยที่จะให้พวกเขาได้รับมรดกจากฐานเดียวกันและดังนั้นคุณต้องใช้ ส่วนต่อประสาน
NikkyD

2
@ SamusArin มันปรากฏ ขึ้น ทุกที่และถือว่าเป็นเรื่องปกติอย่างสมบูรณ์ในภาษาที่รองรับส่วนต่อประสาน คุณหมายถึงอะไร "การใช้ประโยชน์จากความหมายของภาษา"? นี่คือสิ่งที่อินเตอร์เฟซที่จะมีการ
Andres F.

@AndresF ฉันเพิ่งเจอ "ความแตกต่างผ่านอินเทอร์เฟซ" ในตัวอย่างขณะอ่านผ่าน "การวิเคราะห์เชิงวัตถุและการออกแบบด้วยแอปพลิเคชัน" ซึ่งแสดงรูปแบบการสังเกตการณ์ จากนั้นฉันก็ตระหนักถึงคำตอบของฉัน
samis

@AndresF ฉันคิดว่าการมองเห็นของฉันค่อนข้างมืดบอดเกี่ยวกับเรื่องนี้เพราะฉันใช้ความหลากหลายในโครงการสุดท้ายของฉัน ฉันมี 5 ประเภทบันทึกที่มาจากฐานเดียวกัน อย่างไรก็ตามขอขอบคุณสำหรับการตรัสรู้
samis

79

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

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

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

ชนิดที่สามของความแตกต่างเป็นชนิดย่อย polymorphism นี่คือขั้นตอนที่กำหนดไว้ในประเภทที่กำหนดนอกจากนี้ยังสามารถทำงานกับทั้งครอบครัว "ประเภทย่อย" ของประเภทนั้น เมื่อคุณใช้อินเทอร์เฟซหรือขยายคลาสคุณมักจะประกาศความตั้งใจในการสร้างชนิดย่อย ชนิดย่อยที่แท้จริงถูกควบคุมโดยหลักการทดแทนของ Liskovซึ่งบอกว่าถ้าคุณสามารถพิสูจน์บางสิ่งเกี่ยวกับวัตถุทั้งหมดใน supertype คุณสามารถพิสูจน์ได้เกี่ยวกับอินสแตนซ์ทั้งหมดในชนิดย่อย ชีวิตจะได้รับอันตรายแม้ว่าในภาษาอย่าง C ++ และ Java คนทั่วไปจะไม่มีการบังคับใช้และมักจะไม่มีสมมติฐานเกี่ยวกับคลาสที่อาจหรืออาจไม่เป็นจริงเกี่ยวกับคลาสย่อยของพวกเขา นั่นคือรหัสจะถูกเขียนราวกับว่าสามารถพิสูจน์ได้มากกว่าที่เป็นจริงซึ่งก่อให้เกิดปัญหามากมายเมื่อคุณพิมพ์ย่อยอย่างไม่ระมัดระวัง

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

การรับมรดกเป็นสิ่งอันตรายเช่นเดียวกับสิ่งที่มีประสิทธิภาพมากการสืบทอดมีพลังในการทำให้เกิดความเสียหาย ตัวอย่างเช่นสมมติว่าคุณแทนที่เมธอดเมื่อสืบทอดจากคลาสบางคลาส: ทั้งหมดดีและดีจนกระทั่งเมธอดอื่นของคลาสนั้นใช้วิธีที่คุณสืบทอดมาเพื่อให้ทำงานในลักษณะที่แน่นอน . คุณสามารถป้องกันได้บางส่วนด้วยการประกาศวิธีการทั้งหมดที่เรียกใช้โดยวิธีการอื่นของคุณทั้งแบบส่วนตัวและไม่ใช่แบบเสมือน (ขั้นสุดท้าย) เว้นแต่จะได้รับการออกแบบมาให้แทนที่ แม้ว่าสิ่งนี้จะไม่ดีพอเสมอไป บางครั้งคุณอาจเห็นสิ่งนี้ (ในหลอก Java หวังว่าผู้อ่าน C ++ และ C # จะอ่านได้)

interface UsefulThingsInterface {
    void doThings();
    void doMoreThings();
}

...

class WayOfDoingUsefulThings implements UsefulThingsInterface{
     private foo stuff;
     public final int getStuff();
     void doThings(){
       //modifies stuff, such that ...
       ...
     }
     ...
     void doMoreThings(){
       //ignores stuff
       ...
     }
 }

คุณคิดว่าสิ่งนี้น่ารักและมีวิธีการทำ "สิ่งต่าง ๆ " ของคุณเอง แต่คุณใช้การสืบทอดเพื่อรับความสามารถในการทำ "สิ่งอื่น ๆ "

class MyUsefulThings extends WayOfDoingUsefulThings{
     void doThings {
        //my way
     }
}

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

 void dealWithStuff(WayOfDoingUsefulThings bar){
     bar.doThings()
     use(bar.getStuff());
 }

MyUsefulThingsตอนนี้ทำอะไรบางอย่างที่แตกต่างกันกว่าที่คาดไว้เมื่อคุณผ่านมัน อะไรที่แย่กว่านั้นคือคุณอาจไม่รู้ด้วยซ้ำว่าWayOfDoingUsefulThingsทำตามสัญญา อาจdealWithStuffมาจากห้องสมุดเดียวกันWayOfDoingUsefulThingsและgetStuff()ไม่ได้ส่งออกโดยห้องสมุด (คิดว่าเป็นเพื่อนชั้นเรียนใน C ++) ที่แย่กว่านั้นคือคุณได้เอาชนะการตรวจสอบแบบคงที่ของภาษาโดยที่ไม่รู้ตัว: dealWithStuffใช้เวลาWayOfDoingUsefulThingsเพียงเพื่อให้แน่ใจว่ามันจะมีgetStuff()ฟังก์ชั่นที่ทำงานได้ดี

ใช้องค์ประกอบ

class MyUsefulThings implements UsefulThingsInterface{
     private way = new WayOfDoingUsefulThings()
     void doThings() {
        //my way
     }
     void doMoreThings() {
        this.way.doMoreThings();
     }
}

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

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

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

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

  1. ห้ามการสืบทอดหรือการออกแบบสำหรับมัน
  2. ชอบองค์ประกอบ

เป็นแนวทางที่ดีสำหรับเหตุผลข้างต้นและไม่ต้องเสียค่าใช้จ่ายจำนวนมาก


4
คำตอบที่ดี ฉันจะสรุปว่าการพยายามใช้รหัสซ้ำโดยใช้การสืบทอดเป็นเส้นทางที่ผิดธรรมดา การสืบทอดเป็นข้อ จำกัด ที่แข็งแกร่งมาก (imho เพิ่ม "พลัง" คือการเปรียบเทียบที่ผิด!) และสร้างการพึ่งพาที่แข็งแกร่งระหว่างคลาสที่สืบทอดมา การอ้างอิงมากเกินไป = รหัสที่ไม่ดี :) ดังนั้นมรดก (aka "ทำงานเป็น") มักจะส่องสว่างสำหรับการเชื่อมต่อแบบครบวงจร (= ซ่อนตัวความซับซ้อนของการเรียนได้รับมรดก) สำหรับสิ่งอื่นคิดว่าสองครั้งหรือใช้องค์ประกอบ ...
Mar

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

27

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

ตัวอย่างทั่วไปมาจากโลกแห่งการพัฒนาเกม สมมติว่าคุณมีคลาสพื้นฐานสำหรับเอนทิตีเกมทั้งหมดของคุณ - ยานอวกาศของผู้เล่น, มอนสเตอร์, กระสุน, ฯลฯ ; แต่ละประเภทเอนทิตีมีคลาสย่อยของตัวเอง วิธีการรับมรดกจะใช้วิธีการ polymorphic ไม่กี่เช่นupdate_controls(), update_physics(), draw()ฯลฯ และใช้พวกเขาสำหรับแต่ละประเภทรอง อย่างไรก็ตามนี่หมายความว่าคุณกำลังเชื่อมต่อการทำงานที่ไม่เกี่ยวข้อง: มันไม่เกี่ยวข้องกับสิ่งที่วัตถุดูเหมือนว่าจะเคลื่อนไหวและคุณไม่จำเป็นต้องรู้อะไรเกี่ยวกับ AI ในการวาดมัน วิธีการแบบผสมผสานนั้นกำหนดคลาสพื้นฐานหลาย ๆ คลาส (หรืออินเทอร์เฟซ) เช่นEntityBrain(คลาสย่อยใช้ AI หรืออินพุตของผู้เล่น), EntityPhysics(คลาสย่อยใช้ฟิสิกส์การเคลื่อนไหว) และEntityPainter(คลาสย่อยดูแลการวาดภาพ) และคลาสที่ไม่ใช่ polymorphicEntityที่เก็บตัวอย่างหนึ่งของแต่ละ ด้วยวิธีนี้คุณสามารถรวมรูปลักษณ์ใด ๆ กับแบบจำลองฟิสิกส์และ AI ใด ๆ และเนื่องจากคุณแยกพวกเขาออกจากกันรหัสของคุณจะสะอาดกว่ามาก นอกจากนี้ปัญหาเช่น "ฉันต้องการสัตว์ประหลาดที่ดูเหมือนสัตว์ประหลาดบอลลูนในระดับ 1 แต่ทำงานเหมือนตัวตลกบ้าในระดับ 15" หายไป: คุณเพียงแค่นำส่วนประกอบที่เหมาะสมและกาวเข้าด้วยกัน

โปรดทราบว่าวิธีการเรียงองค์ประกอบยังคงใช้การสืบทอดภายในแต่ละองค์ประกอบ แม้ว่าจะเป็นการดีที่คุณจะใช้เพียงอินเทอร์เฟซและการใช้งานที่นี่

"การแยกความกังวล" เป็นวลีสำคัญที่นี่: การเป็นตัวแทนของฟิสิกส์การนำ AI และการดึงเอนทิตี้มาใช้เป็นข้อกังวลสามข้อ ด้วยวิธีการจัดองค์ประกอบความกังวลแต่ละแบบจำลองเป็นหนึ่งชั้น


1
ทั้งหมดนี้เป็นสิ่งที่ดีและสนับสนุนในบทความที่เชื่อมโยงกับคำถามเดิม ฉันจะรัก (เมื่อใดก็ตามที่คุณมีเวลา) ถ้าคุณสามารถให้ตัวอย่างง่ายๆที่เกี่ยวข้องกับหน่วยงานเหล่านี้ทั้งหมดในขณะที่ยังรักษาความหลากหลาย (ใน C ++) หรือชี้ให้ฉันเป็นทรัพยากร ขอบคุณ
MustafaM

ฉันรู้ว่าคำตอบของคุณเก่ามาก แต่ฉันก็ทำแบบเดียวกันกับที่คุณพูดถึงในเกมของฉัน
Sneh

"ฉันต้องการสัตว์ประหลาดที่ดูเหมือน ... " มันสมเหตุสมผลขนาดนี้ยังไง? อินเทอร์เฟซไม่ให้การใช้งานใด ๆ คุณจะต้องคัดลอกโค้ดลักษณะและพฤติกรรมหนึ่งวิธีหรืออย่างอื่น
NikkyD

1
@NikkyD คุณใช้MonsterVisuals balloonVisualsและยกMonsterBehaviour crazyClownBehaviourตัวอย่าง a Monster(balloonVisuals, crazyClownBehaviour), ควบคู่กับMonster(balloonVisuals, balloonBehaviour)และMonster(crazyClownVisuals, crazyClownBehaviour)อินสแตนซ์ที่อินสแตนซ์ที่ระดับ 1 และระดับ 15
Caleth

13

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

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


11

คุณจะเห็นวงจรนี้จำนวนมากในวาทกรรมการพัฒนาซอฟต์แวร์:

  1. คุณลักษณะหรือรูปแบบบางอย่าง (เรียกว่า "รูปแบบ X") ถูกค้นพบว่ามีประโยชน์สำหรับวัตถุประสงค์เฉพาะ โพสต์ในบล็อกเขียนขึ้นเกี่ยวกับคุณธรรมเกี่ยวกับ Pattern X

  2. ขัดต่อ hype นำบางคนจะคิดว่าคุณควรจะใช้รูปแบบ X เมื่อใดก็ตามที่เป็นไปได้

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

  4. แบคแลชทำให้บางคนเชื่อว่า Pattern X นั้นเป็นอันตรายเสมอและไม่ควรใช้

คุณจะเห็นวัฏจักร hype / backlash นี้เกิดขึ้นกับเกือบทุกฟีเจอร์ตั้งแต่GOTOถึงแพทเทิร์นไปจนถึง SQL ถึง NoSQL และถึง, ใช่, การสืบทอด ยาแก้พิษคือพิจารณาบริบทเสมอ

มีการCircleสืบเชื้อสายมาจากShapeเป็นว่าวิธีการรับมรดกที่ควรจะนำมาใช้ในภาษา OO สนับสนุนมรดก

กฎของหัวแม่มือ "ชอบการแต่งมากกว่าการสืบทอด" ทำให้เข้าใจผิดโดยไม่มีบริบท คุณควรเลือกที่จะรับมรดกเมื่อการสืบทอดมีความเหมาะสมมากกว่า ประโยคนี้ถูกนำไปสู่ผู้คนในระยะที่ 2 ในวัฏจักรโฆษณาซึ่งคิดว่าควรใช้การสืบทอดทุกที่ แต่วัฏจักรยังคงดำเนินต่อไปและในวันนี้ดูเหมือนว่าบางคนคิดว่าการรับมรดกนั้นไม่ดีในตัวเอง

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

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