อะไรคือความแตกต่างระหว่างรูปแบบสะพานและรูปแบบกลยุทธ์?


114

ฉันพยายามอ่านบทความมากมายเกี่ยวกับdofactory , wikipedia และหลาย ๆ ไซต์ ฉันไม่รู้เกี่ยวกับความแตกต่างระหว่างรูปแบบสะพานและรูปแบบกลยุทธ์

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

แต่ฉันยังไม่รู้ว่าควรใช้กลยุทธ์ในสถานการณ์ไหนหรือควรใช้สะพานในสถานการณ์ใด

คำตอบ:


66

อรรถศาสตร์ จากวิกิพีเดีย :

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

การมีเพศสัมพันธ์ระหว่างบริบทและกลยุทธ์นั้นเข้มงวดกว่าการมีเพศสัมพันธ์ระหว่างสิ่งที่เป็นนามธรรมและการนำไปใช้ในรูปแบบบริดจ์

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


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

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

3
UML ของ Bridgeค่อนข้างแตกต่างจากสำเนาหนังสือ GoF ของฉัน เครื่องมือนี้สามารถแยกแยะ Bridge จาก Strategy
Fuhrmanator

1
วิกิพีเดียมักเป็นข้อมูลอ้างอิงที่แย่มาก ถูกต้องข้อมูลที่ผิดนั้นถูกลบออกจากเพจ en.wikipedia.org/w/…
Fuhrmanator

2
วิธีที่ฉันได้รับก็คือใช้เทคนิคเดียวกันนี้เพื่อนามธรรมการนำไปใช้งาน (กลยุทธ์) หรือการเชื่อมต่อกับอินเทอร์เฟซ (สะพาน) พฤติกรรมการแลกเปลี่ยนกลยุทธ์อินเทอร์เฟซการแลกเปลี่ยนแบบบริดจ์ (ในที่สุดสิ่งนี้จะช่วยให้การใช้งานกับอินเทอร์เฟซดังกล่าวสามารถสลับได้) กล่าวอีกนัยหนึ่ง Bridge สร้างอินเทอร์เฟซที่เป็นมาตรฐานในด้านหนึ่งและเชื่อมต่อการใช้งานกับอินเทอร์เฟซที่แตกต่างกันในอีกด้านหนึ่ง
Nikaas

55

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

ไวยากรณ์คล้ายกัน แต่เป้าหมายต่างกัน:

  • กลยุทธ์ : คุณมีวิธีอื่น ๆ ในการดำเนินการ ด้วยกลยุทธ์คุณสามารถเลือกอัลกอริทึมในขณะทำงานและคุณสามารถปรับเปลี่ยนกลยุทธ์เดียวโดยไม่มีผลข้างเคียงมากนักในเวลาคอมไพล์
  • Bridge : คุณสามารถแบ่งลำดับชั้นของอินเทอร์เฟซและคลาสรวมเข้ากับการอ้างอิงนามธรรม (ดูคำอธิบาย )

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

11

กลยุทธ์:

  • บริบทที่เชื่อมโยงกับกลยุทธ์: คลาสบริบท (อาจเป็นนามธรรม แต่ไม่ใช่อินเทอร์เฟซจริงๆ! ในขณะที่คุณต้องการสรุปพฤติกรรมที่เฉพาะเจาะจงไม่ใช่การใช้งานทั้งหมด) จะรู้ / มีการอ้างอิงอินเทอร์เฟซกลยุทธ์และการนำไปใช้เพื่อเรียกใช้พฤติกรรมกลยุทธ์บน มัน.
  • Intent คือความสามารถในการสลับพฤติกรรมที่รันไทม์

    class Context {
    
         IStrategy strategyReference;
    
         void strategicBehaviour() {
    
            strategyReference.behave();
         }
    
    }
    

สะพาน

  • สิ่งที่เป็นนามธรรมไม่ได้เชื่อมโยงกับการนำไปใช้: อินเทอร์เฟซนามธรรม (หรือคลาสนามธรรมที่มีนามธรรมพฤติกรรมส่วนใหญ่) จะไม่ทราบ / มีการอ้างอิงอินเทอร์เฟซการใช้งาน
  • เจตนาคือการแยกสิ่งที่เป็นนามธรรมออกจากการนำไปใช้อย่างสมบูรณ์

    interface IAbstraction {
    
        void behaviour1();
    
        .....
    
    }
    
    interface IImplementation {
    
         void behave1();
    
         void behave2();
    
         .....
    
    }
    
    class ConcreteAbstraction1 implements IAbstraction {
    
          IImplementation implmentReference;
    
          ConcreteAbstraction1() {
    
               implmentReference = new ImplementationA() // Some implementation
    
          }
    
          void behaviour1() {
    
                implmentReference.behave1();
    
          }
    
          .............
    
    }
    
    class ConcreteAbstraction2 implements IAbstraction {
    
          IImplementation implmentReference;
    
          ConcreteAbstraction1() {
    
               implmentReference = new ImplementationB() // Some Other implementation
    
          }
    
          void behaviour1() {
    
                implmentReference.behave2();
    
          }
    
          .............
    
    }
    

10

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

กลยุทธ์ VS สะพาน


9

สะพาน : (รูปแบบโครงสร้าง)

รูปแบบสะพานแยกสิ่งที่เป็นนามธรรมและการนำไปใช้และอนุญาตให้ทั้งสองอย่างแตกต่างกันอย่างอิสระ

ใช้รูปแบบนี้เมื่อ:

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

กลยุทธ์: (รูปแบบพฤติกรรม)

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

ใช้รูปแบบกลยุทธ์เมื่อ:

  1. ต้องใช้อัลกอริทึมหลายเวอร์ชัน
  2. พฤติกรรมของคลาสจะต้องเปลี่ยนแปลงแบบไดนามิกในขณะรันไทม์
  3. หลีกเลี่ยงข้อความที่มีเงื่อนไข

กระทู้ที่เกี่ยวข้อง:

คุณใช้ Bridge Pattern เมื่อใด แตกต่างจากรูปแบบ Adapter อย่างไร?

ตัวอย่างรูปแบบกลยุทธ์ในโลกแห่งความจริง


4

ประเภทรูปแบบการออกแบบ

  • พฤติกรรม:รูปแบบแสดงลักษณะของวิธีการที่คลาสหรือวัตถุโต้ตอบและกระจายความรับผิดชอบ
  • โครงสร้าง:รูปแบบจัดการกับองค์ประกอบของคลาสหรือวัตถุ
  • Creational: รูปแบบเกี่ยวข้องกับกระบวนการสร้างวัตถุ

สะพาน (โครงสร้าง)

แยกสิ่งที่เป็นนามธรรมออกจากการนำไปใช้เพื่อให้แต่ละส่วนอาจแตกต่างกันไป อิสระ ใส่คำอธิบายภาพที่นี่

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

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

กลยุทธ์ (พฤติกรรม)

กำหนดกลุ่มของอัลกอริทึมห่อหุ้มแต่ละอันและทำให้ใช้แทนกันได้ ใส่คำอธิบายภาพที่นี่

ในเชิงกลยุทธ์หากเรากำลังดูสถานการณ์ระยะไกล "สถานะ" คือรีโมตทั้งหมดที่เราเปลี่ยนโดยเปลี่ยนการอ้างอิงสถานะของบริบท "ConcreteStateA" (รีโมททีวี) "ConcreteStateB" (DVD Remote)

อ่านเพิ่มเติม:


3
  1. Strategy Pattern ใช้สำหรับการตัดสินใจตามพฤติกรรมในขณะที่Bridge Pattern ใช้สำหรับการตัดสินใจเชิงโครงสร้าง

  2. Brigdeแบบ separats องค์ประกอบนามธรรมจากรายละเอียดการปฏิบัติในขณะที่กลยุทธ์แบบเป็นห่วงการทำขั้นตอนวิธีการใช้แทนกันได้มากขึ้น

รูปแบบกลยุทธ์ใน UML

รูปแบบ Brigde ใน UML

รูปแบบกลยุทธ์ใน Swift:

protocol PrintStrategy {
   func print(_ string: String) -> String
}

class Printer {
   let strategy: PrintStrategy

   init(strategy: PrintStrategy) {
      self.strategy = strategy
    }

  func print(_ string: String) -> String {
     return self.strategy.print(string)
  }
}

class UpperCaseStrategy: PrintStrategy {
    internal func print(_ string: String) -> String {
        return string.uppercased()
    }
}

class LowerCaseStrategy: PrintStrategy {
    internal func print(_ string: String) -> String {
        return string.lowercased()
    }
}

var lower = Printer(strategy: LowerCaseStrategy())
lower.print("I love Software Patterns")

var upper = Printer(strategy: UpperCaseStrategy())
upper.print("I love Software Patterns")

รูปแบบ Brigde ใน Swift:

protocol Appliance {
   func run()
}

protocol Switch {
   let appliance: Appliance {get set}
   func turnOn()
}

class RemoteControl: Switch {
   var appliance: Appliance

   init(appliance: Appliance) {
       self.appliance = appliance
   }

   internal func turnOn() {
      appliance.run()
   }
}

class TV: Appliance {
   internal func run() {
      print("TV is ON")
   }
}

class Stereo: Appliance {
   internal func run() {
      print("Stereo is ON")
   }
}

var tvRemote = RemoteControl.init(appliance: TV())
tvRemote.turnOn()

var stereoRemote = RemoteControl.init(appliance: Stereo())
stereoRemote.turnOn()

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

2

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


1

จากวิกิเกี่ยวกับรูปแบบกลยุทธ์

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

การมีเพศสัมพันธ์ระหว่างบริบทและกลยุทธ์นั้นเข้มงวดกว่าการมีเพศสัมพันธ์ระหว่างสิ่งที่เป็นนามธรรมและการนำไปใช้ในรูปแบบบริดจ์


คุณช่วยอธิบายวลีสุดท้ายอย่างละเอียดได้ไหม
gstackoverflow

1

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


1

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


1

สำหรับรูปแบบกลยุทธ์การใช้งานจะแตกต่างกันไป

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

ทีนี้ถ้าตัว A เป็นนามธรรม ทั้ง A และ B อาจแตกต่างกันไป คุณจะใช้รูปแบบสะพาน


0

ฉันคิดว่ามีความแตกต่างเล็กน้อยระหว่างสิ่งเหล่านี้ในบริบทที่ใช้

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

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

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