In this case, it is important that if you compare two objects, you return the result.
So, basically, you need to separate this comparison in such a way that you can not only add a new type of object to the mix, but also add comparison rules to the mix that this object can process.
Now I also commented on your question: “Sometimes the questions can be too universal,” and the problem is that no matter how I tell you how to do what you ask, it will not help you one bit about the real problem.
If you are not building a rock paper-scissors-X game.
Personally, I would do the following with my own IoC container.
ServiceContainer.Global.RegisterFactory<IHandType>() .FromDelegate(() => RandomRockScissorPaper()); ServiceContainer.Global.RegisterFactory<IHandComparison, DefaultHandComparison>();
(or rather, I would configure above in the app.config file or similar, so that it can be changed after creating the project).
Then, if the user / client / endpoint needs to be redefined to add another type, I would increase the registration as follows (remember that the above are in app.config, so I would replace the ones listed below):
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();
Here I add a new way to solve IHandType, not only preserving the original way, but also adding a new one. This new one will be given the result of calling the old one, and then it will be necessary to decide internally whether a random chance should return the fourth type or the original type (one of the three original ones).
Then I would also override the original comparison rule:
ServiceContainer.Global.RegisterFactory<IHandComparison, DefaultHandComparison>() .ForPolicy("original"); ServiceContainer.Global.RegisterFactory<IHandComparison, NewHandComparison>() .ForPolicy("new") .AsDefaultPolicy() .WithParameters( new Parameter<IHandType>("original"));
Here's how it will be used:
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");
Here's how to implement:
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); } }
After writing all this, I understand that my app.config configuration will not be able to handle delegates, so I need a factory object, but the same thing applies anyway.
You need to decide how to get new hands, and to allow rules for winning hands.