В чем разница между образцом моста и образцом стратегии?

Я пытался прочитать много статей о Dofactory, Wikipedia и многих сайтах. Я понятия не имею о различиях между образцом моста и образцом стратегии.

Я знаю, что оба они отделяют абстракцию от ее реализации и могут изменять реализацию во время выполнения.

Но я до сих пор не знаю, в какой ситуации мне следует использовать стратегию или в какой ситуации я должен использовать бридж.

15 ответов

Решение

Семантика. Из википедии:

Диаграмма классов UML для шаблона "Стратегия" аналогична диаграмме для шаблона "Мост". Тем не менее, эти две модели дизайна не совпадают по своему назначению. В то время как шаблон "Стратегия" предназначен для поведения, шаблон "Мост" предназначен для структуры.

Связь между контекстом и стратегиями более тесная, чем связь между абстракцией и реализацией в паттерне Bridge.

Насколько я понимаю, вы используете шаблон стратегии, когда абстрагируете поведение, которое может быть предоставлено из внешнего источника (например, config может указывать на загрузку некоторой сборки плагина), и вы используете шаблон моста, когда используете те же конструкции, чтобы сделать ваш код немного аккуратнее. Фактический код будет выглядеть очень похоже - вы просто применяете шаблоны по несколько другим причинам.

Шаблон Bridge является структурным шаблоном (КАК ВЫ СОЗДАЕТЕ КОМПОНЕНТ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ?). Паттерн "Стратегия" - это динамический паттерн (КАК ВЫ ХОТИТЕ ПРОВЕДИТЬ ПОВЕДЕНИЕ В ПРОГРАММНОМ ОБЕСПЕЧЕНИИ?).

Синтаксис похож, но цели разные:

  • Стратегия: у вас есть больше способов сделать операцию; со стратегией вы можете выбрать алгоритм во время выполнения и изменить одну стратегию без большого количества побочных эффектов во время компиляции;
  • Мост: вы можете разделить иерархию интерфейса и класса, присоединив его к абстрактной ссылке (см. Объяснение)

Я думал о том же, но недавно мне пришлось использовать мост и понял, что мост использует стратегию и добавляет абстракцию в контекст, чтобы потом вы могли вносить больше изменений, не меняя клиента. При использовании Стратегии без абстракции дизайн не так гибок и может потребовать изменений для клиента позже. Но при использовании всего моста конструкция становится еще более гибкой. Здесь вы можете увидеть, как переход от стратегии к мосту дает больше гибкости. Также мы предполагаем, что теперь "visa" и "master" доступны не только на карточках, но и на телефонах и чипах; и если мы используем мост, гораздо проще добавить эту поддержку.

Стратегия VS Мост

Стратегия:

  • Контекст, связанный со стратегией: Класс контекста (возможно, абстрактный, но не интерфейс! Как вы хотите, чтобы инкапсулировать конкретное поведение, а не всю реализацию) будет знать / содержать ссылку на интерфейс стратегии и реализацию, чтобы вызвать поведение стратегии на Это.
  • Намерение - это способность менять поведение во время выполнения.

    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();
    
          }
    
          .............
    
    }
    

Мост: (структурная схема)

Образец моста отделяет абстракцию и реализацию и позволяет независимо варьироваться.

Используйте этот шаблон, когда:

  1. Абстракции и реализации не были определены во время компиляции
  2. Абстракции и реализации должны быть изменены независимо
  3. Изменения в реализации абстракции не должны влиять на приложение вызывающего
  4. Клиент должен быть изолирован от деталей реализации.

Стратегия: (Поведенческая модель)

Шаблоны стратегий позволяют переключаться между несколькими алгоритмами из семейства алгоритмов во время выполнения.

Используйте шаблон стратегии, когда:

  1. Требуется несколько версий алгоритмов
  2. Поведение класса должно динамически меняться во время выполнения
  3. Избегайте условных заявлений

Похожие сообщения:

Когда вы используете шаблон моста? Чем он отличается от шаблона адаптера?

Пример шаблона стратегии в реальном мире

Типы шаблонов дизайна

  • Поведенческие: шаблоны характеризуют способы взаимодействия классов или объектов и распределяют ответственность
  • Структурные: шаблоны имеют дело с композицией классов или объектов.
  • Созидательный: шаблоны связаны с процессом создания объекта.

Мост (Структурный)

Отсоедините абстракцию от ее реализации, чтобы каждый мог отличаться. независимо.

Возьми пульт. На пульте есть кнопки 1-6. Это конкретный класс на диаграмме выше. Каждая кнопка будет работать по-разному в зависимости от того, используется ли пульт ДУ для телевизора или DVD. Функциональность каждой кнопки абстрагируется от реализации интерфейсом реализатора.

Это позволяет нам изменить работу пульта для каждого устройства.

Стратегия (Поведенческая)

Определите семейство алгоритмов, инкапсулируйте каждый и сделайте их взаимозаменяемыми.

В стратегии, если бы мы смотрели на отдаленный сценарий. "Состояние" - это весь пульт, который мы меняем, меняя ссылку на состояние контекста. "ConcreteStateA" (пульт для телевизора) "concreteStateB" (пульт для DVD).

Дополнительное чтение:

  1. Паттернстратегии используется для поведенческих решений, а паттерн моста - для структурных решений.

  2. Brigde Pattern отделяет абстрактные элементы от деталей реализации, в то время как Strategy Pattern делает алгоритмы более взаимозаменяемыми.

Шаблон стратегии в UML

Бригадный паттерн в 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")

Образец Бригады в Свифте:

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()

Добавляя к ответу willcodejavaforfood, они могут быть одинаковыми в реализации. Однако вы используете стратегию для обмена стратегиями, такими как стратегия сортировки, в то время как вы используете мост для объединения реализаций двух объектов, скажем, обертки базы данных, и сетевого адаптера, чтобы клиентский код мог использовать любой из них, работающий против одного и того же API. Таким образом, наименование говорит само за себя

Из вики о стратегии

Диаграмма классов UML для шаблона "Стратегия" аналогична диаграмме для шаблона "Мост". Тем не менее, эти две модели дизайна не совпадают по своему назначению. В то время как шаблон "Стратегия" предназначен для поведения, шаблон "Мост" предназначен для структуры.

Связь между контекстом и стратегиями более тесная, чем связь между абстракцией и реализацией в паттерне Bridge.

Шаблон стратегии используется, когда вы хотите подключить алгоритм или стратегию во время выполнения. Под категорией паттерна также подразумевается, что она имеет дело с поведением объектов. С другой стороны, мост является структурным паттерном и имеет дело со структурной иерархией объектов. Он отделяет абстракцию от реализации, представляя между ними усовершенствованную абстракцию. Уточненную абстракцию можно спутать с подключенной стратегией времени исполнения (в шаблоне стратегии). Мостовая модель имеет дело со структурными аспектами, предоставляя механизм, позволяющий избежать создания n классов.

Для модели стратегии меняется только реализация.

Предположим, класс A использует класс B, который имеет несколько доступных реализаций. Таким образом, в этом случае B будет абстрактным с фактической реализацией, предоставленной во время выполнения. Это шаблон стратегии

Теперь, если сама А абстрактна. И A, и B могут различаться. Вы бы использовали шаблон моста.

Просто чтобы добавить к тому, что уже было сказано о сравнении шаблонов (разница намерений, ...): шаблон Bridge также намеренно структурирован, чтобы позволить стороне иерархии абстракции изменяться. В таких языках, как C#, это может означать, что у вас есть база абстракций, которая содержит виртуальные методы как способ разрешить предполагаемые изменения, которые не вызывают проблем для существующих потребителей. Кроме того, эти две модели могут казаться идентичными по большей части.

Я думаю, что между ними есть небольшая разница в том контексте, в котором они используются.

Я использую паттерн "Мост" для разделения ортогональных концепций, которые оба они принадлежат большему - чтобы они могли варьироваться независимо. Обычно включает в себя несколько абстракций.

ИМО, модель Стратегии проще или более плоская. Он, безусловно, служит OCP, но не обязательно должен быть частью другой, более масштабной концепции, такой как паттерн Bridge.

Помимо различий в вариантах использования, объясненных другими ответчиками, есть еще о чем подумать.

Похоже, это сочетание и поведенческих моделей. Итак, мы вызываем методы в том же порядке, что и в и изменить свое поведение в зависимости от данного исполнителя, как в шаблон.

Не означает ли это, что два поведенческих паттерна вместе создают структурный паттерн? Либо мы могли бы использовать образец поведения?

В паттерне Стратегия действия "Родителя" для конкретной операции постоянны, тогда как действия "Дочернего" могут варьироваться. Однако в паттерне "Мост" действия Родителя и Дитя могут различаться.

Так, например,

public class Ticket {
    
    Date dateOfTravel;
    int distance;
    Vehicle vehicle;
    Seat  seat;
    
    public float getTotalFare(){
         //depends on 
               //Distance
               //Vehicle - whether Vehicle is AC or non-AC. 
               //Seat - based on the location of the Seat.
     
        //Fare = vehicleBaseFare*seatMultiplier*distance

    }
    
}

В приведенном выше примере варианты зависят от Родителя (расстояние), а также детей (Транспортное средство и Сиденье). Итак, здесь и Vehicle, и Seat действуют как Bridge.

Вот здесь

public class Vehicle {

   TrackingDevice device;

   public Coordinates getCoordinates(){
       return device.getCoordinates();
   }
}

Здесь роль Родителя была постоянной, т.е. ничего! Итак, это был шаблон Стратегии.

Другие вопросы по тегам