Sobes.tech
Middle

Υπάρχουν τρεις μέθοδοι που αλλάζουν τις πληροφορίες του αντικειμένου (αλλάζουν την κατάσταση, αλλάζουν τη σύνθεση των ετικετών και ορίζουν το βάρος). Δεδομένου ότι στο μέλλον προγραμματίζεται να προστεθούν άλλα 10-20 μέθοδοι που αλλάζουν τις πληροφορίες του αντικειμένου (οι ίδιες οι μέθοδοι μπορούν να υλοποιηθούν ως NuGet σε άλλη υπηρεσία), πρέπει να υλοποιηθεί μια ενιαία μέθοδος DoSomethingWithItem που, ανάλογα με τις εισόδους, μπορεί να καλεί οποιαδήποτε αλλαγή στο αντικείμενο. Δηλαδή, μπορεί να πει στη μέθοδο "Άλλαξε την κατάσταση" ή "Ορίστε το βάρος" και η υλοποίησή της θα καλέσει μία από τις μεθόδους όπως StateChanger.Change ή WeightSetter.Set κ.λπ. Οι κλάσεις StateChanger, TagsSetter και WeightSetter μπορούν να τροποποιηθούν. Το σημαντικό είναι να διατηρηθεί η επιχειρηματική λειτουργικότητα.

sobes.tech AI

Απάντηση από 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 при этом остаются с прежним интерфейсом, бизнес-логика сохраняется.