В этом случае важно то, что если вы сравните два объекта , вы получите результат .
Таким образом, вам необходимо разделить это сравнение таким образом, чтобы вы могли не только добавить новый тип объекта в микс, но и добавить в него правила сравнения, которые могут обрабатывать этот объект.
Теперь я также прокомментировал ваш вопрос, сказав, что «Иногда вопросы могут быть слишком обобщенными», и проблема здесь в том, что независимо от того, сколько я вам скажу, как сделать то, что вы спросите о , это не поможет вам ни о какой реальной проблеме.
Если вы не строите игру "Камень-ножницы-бумага-Х".
Лично я бы сделал следующее со своим собственным контейнером IoC.
ServiceContainer.Global.RegisterFactory<IHandType>()
.FromDelegate(() => RandomRockScissorPaper());
ServiceContainer.Global.RegisterFactory<IHandComparison, DefaultHandComparison>();
(точнее, я бы настроил вышеописанное в файле app.config или аналогичном, чтобы его можно было изменить после сборки проекта).
Затем, если пользователю / клиенту / конечной точке необходимо переопределить, чтобы добавить другой тип, я бы увеличил количество регистраций следующим образом (помните, что приведенное выше находится в app.config, поэтому я заменил бы те, что указаны ниже). ):
ServiceContainer.Global.RegisterFactory<IHandType>()
.FromDelegate(() => RandomRockScissorPaper())
.ForPolicy("original");
ServiceContainer.Global.RegisterFactory<IHandType>()
.FromDelegate((IHandType original) => RandomRockScissorPaperBlubb(original))
.WithParameters(
new Parameter<IHandType>("original").WithPolicy("original"))
.ForPolicy("new")
.AsDefaultPolicy();
Здесь я добавляю новый способ разрешения IHandType, не только сохраняя оригинальный путь, но и добавляя новый. Этот новый получит результат вызова старого, а затем должен будет внутренне решить, должен ли случайный случай вернуть четвертый тип или исходный тип (один из трех исходных).
Я бы тогда также переопределил исходное правило сравнения:
ServiceContainer.Global.RegisterFactory<IHandComparison, DefaultHandComparison>()
.ForPolicy("original");
ServiceContainer.Global.RegisterFactory<IHandComparison, NewHandComparison>()
.ForPolicy("new")
.AsDefaultPolicy()
.WithParameters(
new Parameter<IHandType>("original"));
Вот как это будет использоваться:
IHandType hand1 = ServiceContainer.Global.Resolve<IHandType>();
IHandType hand2 = ServiceContainer.Global.Resolve<IHandType>();
IHandComparison comparison = ServiceContainer.Global.Resolve<IHandComparison>();
if (comparison.Compare(hand1, hand2) < 0)
Console.Out.WriteLine("hand 1 wins");
else if (comparison.Compare(hand1, hand2) > 0)
Console.Out.WriteLine("hand 1 wins");
else
Console.Out.WriteLine("equal");
Вот как это сделать:
public interface IHandComparison
{
Int32 Compare(IHandType hand1, IHandType hand2);
}
public class DefaultHandComparison : IHandComparison
{
public Int32 Compare(IHandType hand1, IHandType hand2)
{
... normal rules here
}
}
public class NewHandComparison : IHandComparison
{
private IHandComparison _Original;
public NewHandComparison(IHandComparison original)
{
_Original = original;
}
public Int32 Compare(IHandType hand1, IHandType hand2)
{
if hand1 is blubb or hand2 is blubb then ...
else
return _Original.Compare(hand1, hand2);
}
}
После написания всего этого я понимаю, что моя конфигурация app.config не сможет обрабатывать делегатов, поэтому потребуется фабричный объект, но то же самое применимо.
Вы должны уметь решать вопрос о получении новых рук, а также определять правила для выигрышных рук.