Middle
There are three methods that change product information (change state, modify tags, and set weight). Since there are plans to add another 10-20 methods that change product information (these methods can be implemented as NuGet packages in another service), it is necessary to implement a single method DoSomethingWithItem that, depending on the input parameters, could invoke any product modification. That is, the method could be told "Change state" or "Set weight" and so on, and its implementation would call one of the methods like StateChanger.Change or WeightSetter.Set, etc. The classes StateChanger, TagsSetter, and WeightSetter can be modified. The main goal is to preserve the business functionality. namespace ItemsService { public sealed class StateChanger { public enum State { Active, InActive } public void Change(int itemId, State newState) { } } public sealed class TagsSetter { public void Set(int itemId, string[] tags) { } } public sealed class WeightSetter { public void Set(int itemId, int weight) { } } public sealed class ItemsService { //public void DoSomethingWithItem } }
sobes.tech AI
Answer from AI
To implement a unified method DoSomethingWithItem, which calls the appropriate item modification method based on parameters, it is convenient to use the "Command" pattern or a strategy with delegates.
You can define an interface or a base class for all item modification operations, and then select the required implementation in DoSomethingWithItem based on the operation type.
An example using delegates and an enum for the operation type:
namespace ItemsService
{
public sealed class StateChanger
{
public enum State
{
Active,
InActive
}
public void Change(int itemId, State newState)
{
// implementation of state change
}
}
public sealed class TagsSetter
{
public void Set(int itemId, string[] tags)
{
// implementation of setting tags
}
}
public sealed class WeightSetter
{
public void Set(int itemId, int weight)
{
// implementation of setting weight
}
}
public sealed class ItemsService
{
private readonly StateChanger _stateChanger = new StateChanger();
private readonly TagsSetter _tagsSetter = new TagsSetter();
private readonly WeightSetter _weightSetter = new WeightSetter();
public enum OperationType
{
ChangeState,
SetTags,
SetWeight
// new operations can be added later
}
public void DoSomethingWithItem(int itemId, OperationType operation, object value)
{
switch (operation)
{
case OperationType.ChangeState:
if (value is StateChanger.State state)
_stateChanger.Change(itemId, state);
else
throw new ArgumentException("Invalid value for ChangeState");
break;
case OperationType.SetTags:
if (value is string[] tags)
_tagsSetter.Set(itemId, tags);
else
throw new ArgumentException("Invalid value for SetTags");
break;
case OperationType.SetWeight:
if (value is int weight)
_weightSetter.Set(itemId, weight);
else
throw new ArgumentException("Invalid value for SetWeight");
break;
default:
throw new NotSupportedException("Operation not supported");
}
}
}
}
This approach allows centralized invocation of the necessary methods, and when adding new operations, it is enough to extend the enum and add the corresponding logic. The classes StateChanger, TagsSetter, and WeightSetter remain with the same interface, preserving business logic.