Это не совсем то, о чем вы просите, но оно дает аналогичный эффект ...
Почему бы не определить интерфейс для ваших операций.ClassA реализует интерфейс.Ваши собственные стратегии также реализуют интерфейс.ClassA внутренне создает реализацию интерфейса «по умолчанию» при запуске (когда создается экземпляр ClassA), но также имеет свойство, позволяющее установить интерфейс.Интерфейс может даже позволить настраиваемой стратегии указывать, какие члены интерфейса, который он фактически реализует:
interface IStrategy
{
void Operation1(int x, int y);
void Operation2(string a, string b);
}
class ClassA : IStrategy
{
private IStrategy builtInStrategy = new BuiltInStrategy();
public IStrategy CustomStrategy { get; set; }
void Operation1(int x, int y);
{
if (CustomStrategy != null)
{
CustomStrategy.Operation1(x, y);
}
else
{
builtInStrategy.Operation1(x, y);
}
}
void Operation2(string a, string b)
{
if (CustomStrategy != null)
{
CustomStrategy.Operation2(a, b);
}
else
{
builtInStrategy.Operation2(a, b);
}
}
}
Вы можете указать в качестве части интерфейса IStrategy способ для пользовательской стратегии указать, что она не является«переопределение» конкретной операции.Возможно, он может вернуть bool
вместо void, или каждая операция может иметь параметр out bool
, для которого установлено значение false, если пользовательская стратегия не переопределяет операцию.
В зависимости от того, сколько операций можетбыть переопределенным, вы можете даже рассмотреть вопрос о назначении каждой операции свой собственный интерфейс.Операции могут быть сгруппированы в интерфейсе, если нецелесообразно реализовывать одну операцию без выполнения других операций.
interface IOperation1
{
void Operation1(int x, int y);
}
interface IOperation2
{
void Operation2(string a, string b);
}
interface IMath
{
int Add(int i, int j);
int Subtract(int i, int j);
int Multiply(int i, int j);
int Divide(int i, int j);
}
interface IStrategy
{
//What operations should the Strategy have?
}
class ClassA : IOperation1, IOperation2, IMath
{
public IStrategy CustomStrategy { get; set; }
public void Operation1(int x, int y)
{
IOperation1 op1 = CustomStrategy as IOperation1;
if (op1 != null)
{
op1.Operation1(x, y);
}
else
{
//Do ClassA's Operation1 logic here
}
}
public void Operation2(string a, string b)
{
IOperation2 op2 = CustomStrategy as IOperation2;
if (op2 != null)
{
op2.Operation2(a, b);
}
else
{
//Do ClassA's Operation2 logic here
}
}
//
// And so on ...
//
}