Sobes.tech
Middle

Esistono tre metodi che modificano le informazioni dell'articolo (modificano lo stato, cambiano la composizione dei tag e impostano il peso). Poiché in futuro si prevede di aggiungere altri 10-20 metodi che modificano le informazioni dell'articolo (i metodi stessi possono essere implementati come NuGet in un altro servizio), è necessario implementare un unico metodo DoSomethingWithItem che, in base ai parametri di input, possa chiamare qualsiasi modifica dell'articolo. Cioè, al metodo si può dire "Cambia lo stato" o "Imposta il peso" e la sua implementazione chiamerà uno dei metodi come StateChanger.Change o WeightSetter.Set, ecc. Le classi StateChanger, TagsSetter e WeightSetter possono essere modificate. L'importante è mantenere la funzionalità aziendale.

sobes.tech AI

Risposta dell'AI

Для реализации единого метода 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 при этом остаются с прежним интерфейсом, бизнес-логика сохраняется.