LINUX.ORG.RU

Подскажите по шаблону стратегия

 , ,


0

1

Я сегодня разобрал шаблон стратегия, на примере JS вот отсюда

https://ru.wikipedia.org/wiki/Стратегия_(шаблон_проектирования)#.D0.9F.D1.80....

То что там нписано в самой статье, я вобще нихрена не понял, какая-то билеберда. Решил, что по коду пойму. Не понял:) Сам код то я понял, что он делает, собственно, я его даже «улучшил», путем выкидывания разногоо рода говна. Вот что в моей версии получилось

create=Object.create


Strategy={
  exec: function(){},
  message: "foo"
}

Strategy.WindowStatus=create(Strategy)
Strategy.NewWindow=create(Strategy)
Strategy.Alert=create(Strategy)

with(Strategy){
  WindowStatus.exec=function(){status=message}
  NewWindow.exec=function(){
    open("", "_blank").document.write("<html>"+message+"</html>")
  }
  Alert.exec=function(){alert(message)}
}

with(Strategy){
 WindowStatus.exec()
 NewWindow.exec()
 Alert.exec()
}
Этот код делает то же самое, только меньше по объему раза в 3.

Сначала пара вопросов по реализации.

Я пропускаю момент засирания синтаксическим мусором, это ладно, проехали.

Зачем они там наследуют не от самого Strategy, а от его экземпляров? То есть, фактически все эти их подклассы имеют разных родителей. В этом есть какой-то смысл?

Дальше, я не понял, зачем они создают обертку «Context»?

Далее, они зачем-то создают экземпляры для каждого класса, хотя необходимости в этом тоже никакой нет, можно также вызвать эти экзеки из самих классов(что я и сделал), но это, ладно, может быть просто для понта создали экземпляры, не столь важно.

Теперь самый главный вопрос: В ЧЕМ ЗАКЛЮЧАЕТСЯ СТРАТЕГИЯ? Уж не в том ли, чтобы поочередно вызвать 3 функции?

Заранее спасибо.

Ответ на: комментарий от TDrive

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

Мне это, кстати, напомнило вот такой финт ушами, который я делаю на Io

Sequence parseQuery := method(
   findRegex("(?<=\\?)(\\w+=[^&]+(\\&|$))+") ifNil(return) string prependProto(QueryString)
)


QueryString := String clone do(
 asList := method(
   split("&") map(split("="))
 )
 asMap := method(asList asMap)
 asJson := method(asMap asJson)
)

"http://foo.bar?foo=bar&bar=baz" parseQuery asJson print # --> {"bar":"baz","foo":"bar"}
объект строки на сообщение parseQuery, отдает сабкласс строки, который имеет уже свои собственные слоты.

javaQest
() автор топика
Ответ на: комментарий от javaQest

отдает сабкласс строки

экземпляр сабкласса строки

//fixed

javaQest
() автор топика
Ответ на: комментарий от TDrive

то есть метод parseQuery возвращает вроде бы подстроку, которая с виду ничем вроде бы не отличается от просто строки

"http://foo.bar?foo=bar&bar=baz" parseQuery print # --> foo=bar&bar=baz
Но на деле, это экземпляр и строки и QueryString одновременно
"http://foo.bar?foo=bar&bar=baz" parseQuery asJson print # --> {"bar":"baz","foo":"bar"}

В этом определеннно есть что-то схожее с тем что ты говоришь.

javaQest
() автор топика
Ответ на: комментарий от TDrive

То есть, на Io пример, с архивами, который ты приводил, выглядел бы как то так


Archiver with("foo.zip") asZip decompress

тут asZip — это и есть стратегия.

javaQest
() автор топика
Ответ на: комментарий от javaQest

не думаю, фишка стратегии в том что она в общем то самостоятельна относительно контекста

QueryString := String clone do(
 asList := method(
   split("&") map(split("="))
 )
 asMap := method(asList asMap)
 asJson := method(asMap asJson)
)
Тут у тебя четко определяются возможные варианты стратегий.
Archiver with("foo.zip") asZip decompress
А тут стратегия не передается в контекст а просто выбирается нужная из заранее заготовленного в контексте набора.

Так вот фишка паттерна стратегии в том что стратегии можно использовать с разыми контекстами, это как библиотека алгоритмов схожих по смыслу и с одинаковым интерфейсом. Вот есть у нас набор стратегий zip, rar, 7z... его можно использовать с файлами в контексте Archiver, а можно использовать в каком нибудь TCPArchiver для архивации данных перед отправкой по сети, главное чтобы стратегии zip, rar, 7z реализовывали единый интерфейс который и для Archiver и для TCPArchiver подойдет.

TDrive ★★★★★
()
Ответ на: комментарий от javaQest

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

asList := method(
   split("&") map(split("="))
 )
asMap := method(asList asMap)
asJson := method(asMap asJson)
Это уже конечно попахивает god object, но мы сейчас не об этом, да и малоли какие задачи в программировании встречаются.

TDrive ★★★★★
()
Ответ на: комментарий от javaQest

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

Так вот все твои попытки реализации паттерна стратегия на этой задаче полностью сливаюся, а пример из википедии подходит идеально.

TDrive ★★★★★
()
Последнее исправление: TDrive (всего исправлений: 1)
Ответ на: комментарий от TDrive

А тут стратегия не передается в контекст а просто выбирается нужная из заранее заготовленного в контексте набора.

тут стратегией можно считать Archiver, а asZip как раз возвратит экземпляр контекста, увловно. А дальше ты делаешь что-то с этим экземпляром, в данном случае, шлешь сообщение decompress. Тут прямая анология прослеживается с тем примером на википедии. Просто там другой синтаксис. мы могли бы переписать этот пример так


Zip with(Archiver with("foo.zip")) decompress

javaQest
() автор топика
Ответ на: комментарий от javaQest

Просто мы добавили слот asZip классу Archiver, этот слот (метод) берет текущий объект (экземпляр Archiver), и возвращает экземпляр Zip, сконфигурированный с этим объектом, чтобы был сахар слаже.

javaQest
() автор топика
Ответ на: комментарий от javaQest

Это Вот так можно выразить, более обобщенно


Strategy with(object) asContext doStaff
 ==
Context with(Strategy with(object)) doStaff

javaQest
() автор топика

То что там нписано в самой статье, я вобще нихрена не понял, какая-то билеберда. Решил, что по коду пойму. Не понял:)

За это мы тебя и любим 🙌😁👶💩

holuiitipun
()
Ответ на: комментарий от TDrive

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

Завтра я попробую реализовать, с моим подходом это, если время будет спать уже надо. По моему, все там прекрасно ложится.

javaQest
() автор топика
Ответ на: комментарий от javaQest

Во вторых, мне нравиться, что в JS можно (пока?) писать ООП без сахара.

Даже в твоей мамке так можно 😈

holuiitipun
()
Ответ на: комментарий от holuiitipun

Ты еще не забыл, как я тебя на асинхронности попустил? А, не, не забыл, это заметно.

И че ты вообще влез в ООП-тред, ты же по факториалам специалист, вот и иди, дрочи свои факториалы дальше.

javaQest
() автор топика
Ответ на: комментарий от javaQest

Ты еще не забыл, как я тебя на асинхронности попустил? А, не, не забыл, это заметно.

Где ты не понял различие между блокирующими операциями и твоей мамкой?

holuiitipun
()
Ответ на: комментарий от javaQest

иди, дрочи свои факториалы дальше.

Это специальность твоей мамки 👮👯👮

holuiitipun
()
Ответ на: комментарий от holuiitipun

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

javaQest
() автор топика
Ответ на: комментарий от Tanger

А причем тут ООП? Шаблон стратегия можно и без ООП спокойно использовать.

hlebushek ★★
()

самый главный вопрос: В ЧЕМ ЗАКЛЮЧАЕТСЯ СТРАТЕГИЯ?

В том, чтоб писать тупняк на ЛОР, конечно же.

hateyoufeel ★★★★★
()
Ответ на: комментарий от javaQest

Я могу еще проще написать

console.log("bark");
console.log("meow");
console.log("quack");

Я твой код «улучшил», путем выкидывания разногоо рода говна.
Оверинжиниринг мне не нужен. Я буду плясать от задачи. Если нужно расширять, буду рефакторить. Сразу учитывать в реализации все возможные варианты — это путь в никуда. А у тебя оверхед по памяти и вообще так пишут только упоротые архитектурные астронавты.

goingUp ★★★★★
()
Ответ на: комментарий от javaQest

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

function superSmartCodeWithoutUselessThings() {
  console.log("bark");
  console.log("meow");
  console.log("quack");
}

goingUp ★★★★★
()
Ответ на: комментарий от goingUp

Не, это ты не понял. Тот кусок кода, на который я отвечал, ВСЕГДА может быть переписан моим способом. А твой код не соответствует семантически.

javaQest
() автор топика
Ответ на: комментарий от goingUp

Все там есть. Этот код вообще эквивалентен его коду, просто я там заюзал объекты, можно и ф-ции,

mkSound=function(sound){global[sound]=function(){console.log(sound)}}

mkSound("quack")
mkSound("meow")
mkSound("bark")

Speaker=function(sound){
 this.action=sound
}

Speaker.prototype.setType=function(sound){this.action=sound}
Speaker.prototype.speack=function(){this.action()}
Это то же самое, что и у него, только без свитча.

javaQest
() автор топика
Ответ на: комментарий от javaQest

Все там есть.

Если ты про Animal, то это более похоже на объект-животное, чем на объект-стратегию. А издавание звука объектом-животным - это полиморфизм, а не стратегия. Суть шаблона «стратегия» - разные объекты (разных классов) на разные стратегии, которые могут иметь разный код, использовать наследование, композицию и прочие фишки ООП, а ты все пытаешься в один объект (один класс) всунуть и использовать полиморфизм для реализации стратегии.

goingUp ★★★★★
()

Я сегодня разобрал шаблон стратегия, на примере JS

А я вот сегодня лямбда-функции на Паскале разбирал.

Улавливаешь суть своего троллинга вопросика?

d_Artagnan ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.