Sobes.tech
Middle

Postoje tri metode koje menjaju informacije o artiklu (menjaju stanje, menjaju sastav tagova i postavljaju težinu). Kako se planira dodavanje još 10-20 metoda koje menjaju informacije o artiklu (same metode mogu biti implementirane kao NuGet u drugom servisu), potrebno je implementirati jedinu metodu DoSomethingWithItem koja, u zavisnosti od ulaznih parametara, može pozvati bilo kakvu promenu artikla. To jest, metodi se može reći "Promeni stanje" ili "Postavi težinu" i njena implementacija će pozvati jednu od metoda kao što su StateChanger.Change ili WeightSetter.Set itd. Klase StateChanger, TagsSetter i WeightSetter mogu se menjati. Važno je sačuvati poslovnu funkcionalnost.

sobes.tech АИ

Одговор од АИ

Для реализации единого метода DoSomethingWithItem, который в зависимости от параметров вызывает нужный метод изменения товара, удобно использовать паттерн "Команда" или стратегию с делегатами.

Можно определить интерфейс или базовый класс для всех операций изменения товара, а затем в DoSomethingWithItem выбирать нужную реализацию по типу операции.

Пример с использованием делегатов и enum для типа операции:

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
    {
        private readonly StateChanger _stateChanger = new StateChanger();
        private readonly TagsSetter _tagsSetter = new TagsSetter();
        private readonly WeightSetter _weightSetter = new WeightSetter();

        public enum OperationType
        {
            ChangeState,
            SetTags,
            SetWeight
            // позже можно добавить новые операции
        }

        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");
            }
        }
    }
}

Такой подход позволяет централизованно вызывать нужные методы, а при добавлении новых операций достаточно расширить enum и добавить соответствующую логику. Классы StateChanger, TagsSetter и WeightSetter при этом остаются с прежним интерфейсом, бизнес-логика сохраняется.