Вопрос больше о терминах. Хочется понять, как можно данное решение объяснять в общем случае.
Решение выглядит просто (C#):
static class FuncProvider {
public Func<int, int, int> Sum = (a,b) => a+b; // delegate or pointer to function
}
class SomeObject {
public void Method(int a, int b)
{
var r = FuncProvider.Sum(a, b);
}
}
// standard code var obj = new SomeObject();
obj.Method(1,2);
// code with overriden Sum function
FuncProvider.Sum = (a,b) => {
if (/*some condition*/) return a+b;
return 0;
};
var obj = new SomeObject();
obj.Method(1,2);
Код показывает только саму суть: возможность подменить логику без изменения основного функционала. Дилемма состоит в том, чтобы подобрать наиболее адекватное описание данного решения, чтобы не пускаться в описание деталей типа: "надо сделать статик, там сделать функтор, чтобы вытащить метод и бла-бла-бла".
Что это Strategy или Servant? Или другой какой-то? Поделитесь мыслями, плиз?
Re: К какому паттерну ближе решение (статик делегат используется в других класса
Здравствуйте, another_coder, Вы писали:
_>Код показывает только саму суть: возможность подменить логику без изменения основного функционала. Дилемма состоит в том, чтобы подобрать наиболее адекватное описание данного решения, чтобы не пускаться в описание деталей типа: "надо сделать статик, там сделать функтор, чтобы вытащить метод и бла-бла-бла". _>Что это Strategy или Servant? Или другой какой-то? Поделитесь мыслями, плиз?
Это тупо глобальная статическая переменная.
Почему бы не сделать явную передачу зависимости?
Насчёт синтаксиса не уверен, т.к. плохо знаю c#
class SomeObject
{
private const Func<int, int, int> Sum;
public SomeObject(Func<int, int, int> f) {this.Sum=f;}
}
// standard code var obj = new SomeObject(FuncProvider.Sum);
obj.Method(1,2);
// или так, если SomeObject иммутабеленstatic class SomeObjectDefaults
{
public const SomeObject DEFAULT = new SomeObject((a, b) => a+b);
}
...
var obj = SomeObjectDefaults.DEFAULT;
obj.Method(1,2);
// code with overriden Sum functionvar obj = new SomeObject((a,b) => {
if (/*some condition*/) return a+b;
return 0;
});
obj.Method(1,2);
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: К какому паттерну ближе решение (статик делегат используется в других кла
Здравствуйте, ·. ·>Почему бы не сделать явную передачу зависимости?
В общем случае так лучше. Явно видная зависимость — это хорошо и к этому следует стремиться.
Но так не всегда получается сделать код простым. Например, в случае с некоторым ресурсом, который должен освобождаться сразу после использования. При инициализации необходимо по-разному настроить в зависимости от окружения (prod, test, dev). В этом случае использовать некий DEFAULT не получится, т.к. надо создавать объект каждый раз. А чтобы не усложнять конструктор объекта использовать monkey patch. В этом случае все сведется к решению со статик-переменной.
Re[3]: К какому паттерну ближе решение (статик делегат используется в других кла
Здравствуйте, another_coder, Вы писали:
_>В общем случае так лучше. Явно видная зависимость — это хорошо и к этому следует стремиться. _>Но так не всегда получается сделать код простым. Например, в случае с некоторым ресурсом, который должен освобождаться сразу после использования. При инициализации необходимо по-разному настроить в зависимости от окружения (prod, test, dev). В этом случае использовать некий DEFAULT не получится, т.к. надо создавать объект каждый раз. А чтобы не усложнять конструктор объекта использовать monkey patch. В этом случае все сведется к решению со статик-переменной.
для этого можно использовать стратегии, а не делать вещи, как в динамических языках.
правда, кода будет побольше.
...coding for chaos...
Re[4]: К какому паттерну ближе решение (статик делегат используется в других кла
Здравствуйте, another_coder, Вы писали:
_>·>Почему бы не сделать явную передачу зависимости? _>В общем случае так лучше. Явно видная зависимость — это хорошо и к этому следует стремиться. _>Но так не всегда получается сделать код простым. Например, в случае с некоторым ресурсом, который должен освобождаться сразу после использования. При инициализации необходимо по-разному настроить в зависимости от окружения (prod, test, dev). В этом случае использовать некий DEFAULT не получится, т.к. надо создавать объект каждый раз. А чтобы не усложнять конструктор объекта использовать monkey patch. В этом случае все сведется к решению со статик-переменной.
Фабрику тогда для SomeObject можно сделать, java просто делаешь тип Provider<SomeObject>, в шарпе не знаю... В случае с языком с лямбдами и код будет простой.
А статик-переменные — абсолютное зло, только в простом коде-прототипе-на-выброс можно простить.
На крайний случай, статик-иммутабельная переменная без собственных зависимостей.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[4]: К какому паттерну ближе решение (статик делегат используется в других кла
Здравствуйте, ·, Вы писали:
·>Здравствуйте, another_coder, Вы писали:
_>>·>Почему бы не сделать явную передачу зависимости? _>>В общем случае так лучше. Явно видная зависимость — это хорошо и к этому следует стремиться. _>>Но так не всегда получается сделать код простым. Например, в случае с некоторым ресурсом, который должен освобождаться сразу после использования. При инициализации необходимо по-разному настроить в зависимости от окружения (prod, test, dev). В этом случае использовать некий DEFAULT не получится, т.к. надо создавать объект каждый раз. А чтобы не усложнять конструктор объекта использовать monkey patch. В этом случае все сведется к решению со статик-переменной. ·>Фабрику тогда для SomeObject можно сделать, java просто делаешь тип Provider<SomeObject>, в шарпе не знаю... В случае с языком с лямбдами и код будет простой. ·>А статик-переменные — абсолютное зло, только в простом коде-прототипе-на-выброс можно простить. ·>На крайний случай, статик-иммутабельная переменная без собственных зависимостей.
не понял какой вариант вы описываете и категоризм про статик-переменные тоже не понял
Re[5]: К какому паттерну ближе решение (статик делегат используется в других кла
Здравствуйте, another_coder, Вы писали:
_>Здравствуйте, ·, Вы писали:
_>·>Здравствуйте, another_coder, Вы писали:
_>>>·>Почему бы не сделать явную передачу зависимости? _>>>В общем случае так лучше. Явно видная зависимость — это хорошо и к этому следует стремиться. _>>>Но так не всегда получается сделать код простым. Например, в случае с некоторым ресурсом, который должен освобождаться сразу после использования. При инициализации необходимо по-разному настроить в зависимости от окружения (prod, test, dev). В этом случае использовать некий DEFAULT не получится, т.к. надо создавать объект каждый раз. А чтобы не усложнять конструктор объекта использовать monkey patch. В этом случае все сведется к решению со статик-переменной. _>·>Фабрику тогда для SomeObject можно сделать, java просто делаешь тип Provider<SomeObject>, в шарпе не знаю... В случае с языком с лямбдами и код будет простой. _>·>А статик-переменные — абсолютное зло, только в простом коде-прототипе-на-выброс можно простить. _>·>На крайний случай, статик-иммутабельная переменная без собственных зависимостей.
_>не понял какой вариант вы описываете
Заменить "new" на фабрику. как-то так
...
// standard code
Provider<SomeObject> someObjectProvider = () => new SomeObject((a, b) => a+b);
...
SomeObject obj = someObjectProvider.get();
obj.Method(1,2);
// code with overriden Sum function
Provider<SomeObject> someObjectProvider = () => new SomeObject((a, b) {
if (/*some condition*/) return a+b;
return 0;
});
...
SomeObject obj = someObjectProvider.get();
obj.Method(1,2);
_> и категоризм про статик-переменные тоже не понял
Не используй статик-переменные.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[6]: К какому паттерну ближе решение (статик делегат используется в других кла
Здравствуйте, another_coder, Вы писали:
_>·>Не используй статик-переменные. _>Про фабрику мысль понял. _>Но почему такой категоризм про статик-переменные?
Потому что это по сути глобальная переменная со всеми вытекающими. Всякие сложности управления зависимостями (вот понадобится тебе в одной из overriden Sum function ещё какая-нибудь зависимость), непонятный порядок инициализации, проблемы с многопоточностью, побочные эффекты и сложность потом это всё поменять. Т.е. статик-переменная это типичный технический долг.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: К какому паттерну ближе решение (статик делегат используется в других класса
_>Код показывает только саму суть: возможность подменить логику без изменения основного функционала. Дилемма состоит в том, чтобы подобрать наиболее адекватное описание данного решения, чтобы не пускаться в описание деталей типа: "надо сделать статик, там сделать функтор, чтобы вытащить метод и бла-бла-бла".
Обычное делегирование, только нужно экземпляр класса FuncProvider передать в конструктор класса SomeObject и сохранить в переменной класса.
Re[3]: К какому паттерну ближе решение (статик делегат используется в других кла
_> При инициализации необходимо по-разному настроить в зависимости от окружения (prod, test, dev). В этом случае использовать некий DEFAULT не получится, т.к. надо создавать объект каждый раз.
Выглядит как каноничный dependency injection
_>использовать некий DEFAULT _> А чтобы не усложнять конструктор объекта использовать monkey patch. В этом случае все сведется к решению со статик-переменной.
Вместо статик переменной лучше фабричный метод тогда уж. Который в зависимости от твоего DEFAULT<prod/dev/test> будет давать нужные объекты
Re[8]: К какому паттерну ближе решение (статик делегат используется в других кла
Здравствуйте, another_coder, Вы писали:
_>Что это Strategy или Servant? Или другой какой-то? Поделитесь мыслями, плиз?
Вот так на вскидку не припомню ни одного паттерна, в [канонической] реализации которого [на шарпе] использовались бы глобальные изменяемые переменные
А ведь именно в ней вся соль вашего решения, как я понял из обсуждения — меньше кода, удобство, прочее…
Простите, но по старой русской традиции не могу не удержаться от совета:раз уж задумались о паттернах, опишите свою задачу и попросите подсказать вам лучшее для неё решение.
Re[9]: К какому паттерну ближе решение (статик делегат используется в других кла
Здравствуйте, woah, Вы писали:
W>·>Потому что это по сути глобальная переменная со всеми вытекающими. W>Если она readonly и состояние не менять, то вытикающих будет минимум.
Я об этом уже писал. И в коде топика она не readonly.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: К какому паттерну ближе решение (статик делегат используется в других класса
Здравствуйте, another_coder, Вы писали:
_>Вопрос больше о терминах. Хочется понять, как можно данное решение объяснять в общем случае. _>Решение выглядит просто (C#): _>
_>
_>Код показывает только саму суть: возможность подменить логику без изменения основного функционала. Дилемма состоит в том, чтобы подобрать наиболее адекватное описание данного решения, чтобы не пускаться в описание деталей типа: "надо сделать статик, там сделать функтор, чтобы вытащить метод и бла-бла-бла". _>Что это Strategy или Servant? Или другой какой-то? Поделитесь мыслями, плиз?
Можно всё что хошь. Твой пример сильно мелкий, если буквально то он вырождается примерно в такое ибо не ясна роль SomeObject
FuncProvider.Sum(a, b);
Если хочется паттернов, то чуть не все паттерны делают именно это
Стратегия
class SomeObject
{
private FuncProvider _provider;
public SomeObject (FuncProvider provider)
{
_provider = provider;
}
public void Method(int a, int b)
{
var r = _provider.Sum(a, b);
}
}
Еще фокус
class SomeObject
{
virtual public void Sum(int a, int b)
{
...
}
public void Method(int a, int b)
{
var r = _provider.Sum(a, b);
}
}
class SomeDerived : SomeObject
{
override virtual public void Sum(int a, int b)
{
...
}
}
А так же легко сгодятся
1. chain of responsibility
2. singleton — ты его практически изобрёл.
3. composite
4. decorator
5. visitor
и еще целая куча паттернов, например — MVC