как решить это дублирование кода + добавить еще один метод - PullRequest
2 голосов
/ 08 августа 2011

У меня есть 3 класса:

class First {
    public void SetA(){ ... }
    public void SetB(){ ... }
    public void SetC(){ ... }
    public void SetD(){ ... }
    public void SetZ(){ ... }
}

class Second {
    public void SetC(){ ... }
    public void SetD(){ ... }
    public void SetE(){ ... }
    public void SetF(){ ... }
    public void SetX(){ ... }
}

class Third{
    public void SetA(){ ... }
    public void SetB(){ ... }
    public void SetE(){ ... }
    public void SetF(){ ... }
    public void SetY(){ ... }
}

Как видите, я дублирую код теми же методами.
Вчера я понял, что иногда я хотел бы добавить еще один комментарий в каждый метод.
Итак, я ищу способ решить обе эти проблемы.Одно решение, о котором я подумал:

  1. Создать интерфейс:

    interface IAllMethods {
            void SetA();
            void SetB();
            void SetC();
            void SetD();
            void SetE();
            void SetF();
            void SetX();
            void SetY();
            void SetZ();
    }
    
  2. Создать реализацию по умолчанию:

    class DefaultAllMethods {
            public void SetA(){ ... }
            public void SetB(){ ... }
            public void SetC(){ ... }
            public void SetD(){ ... }
            public void SetE(){ ... }
            public void SetF(){ ... }
            public void SetX(){ ... }
            public void SetY(){ ... }
            public void SetZ(){ ... }
    }
    
  3. Создайте еще одну реализацию, используя шаблон декоратора, чтобы добавить дополнительную команду:

    class ExtraAllMethods {
            private IAllMethods _allMethods;
            public ExtraAllMethods (IAllMethods allMethods) {
                _allMethods=allMethods;
            }
            public void SetA(){ 
                _allMethods.SetA();
                extraMethod();
            }
            public void SetB(){ 
                _allMethods.SetB();
                extraMethod();
            }
            public void SetC(){ 
                _allMethods.SetC();
                extraMethod();
            }
            ..
            ..
            ..
    }
    
  4. Используйте реализацию desire внутри классов First, Second и Third.Например:

    class Third{
        private IAllMethods  _allMethods;
        public Third(IAllMethods allMethods) {
            _allMethods=allMethods;
        }
        public void SetA(){ _allMethods.SetA(); }
        public void SetB(){ _allMethods.SetB(); }
        ..
        ..
        ..
    }
    

Что вы думаете об этом решении?Есть ли лучший дизайн для этой потребности?

ОБНОВЛЕНИЕ
Люди спрашивают о реальном бизнесе, так вот оно: у меня есть 3 типа передачи: TransmissionA, TransmissionB, TransmissionC каждыйпередача имеет много параметров (членов или свойств).Например, TransmissionA имеет WorkerId, CustomerId, MessageName и так далее.TransmissionB имеет WorkerId и MessageName, но не CustomerId.TransmissionC имеет WorkerId, CustomerId, но без MessageName.Это только пример - в моей ситуации у меня есть еще много свойств для каждой передачи.Каждое свойство имеет метод Set.
Теперь появилась новая необходимость.Где-то в системе есть опция под названием «Обновить задачу».Если опция включена, то мне нужно обновить соответствующую задачу в каждом методе Set.Вот почему я подумал о схеме декоратора.

Ответы [ 4 ]

2 голосов
/ 08 августа 2011
  1. Интерфейс не очень хорошая идея, поскольку его разработчики предоставляют функциональность только для подмножества методов, предоставляемых интерфейсом.
  2. Шаблон декоратора не может использоваться здесь, потому что он используется для добавления функциональности, его нельзя использовать для изменения API, например, для добавления методов. См. этот ответ для получения дополнительной информации.
  3. Если у вас один и тот же метод с одинаковым кодом в разных классах, он должен быть извлечен в его собственный класс и использован другими. В настоящее время ваши занятия, скорее всего, нарушают принцип единоличной ответственности .
0 голосов
/ 08 августа 2011

Вы можете определить интерфейс для каждого отдельного метода и реализацию по умолчанию для каждого интерфейса и заставить ваши классы реализовывать только необходимые интерфейсы и параметризироваться через конструктор с реализациями по умолчанию для декорирования.

0 голосов
/ 08 августа 2011

это будет работать, но вместо введения всезнающего интерфейса и базовых классов реализации, содержащих все методы (и, следовательно, знания всей совокупности методов), вы также можете пойти на более детальный подход и просто создать единый интерфейси базовая реализация для каждого метода.Это было бы более расширяемым, и вы могли бы присоединить их так же просто, как плагин, если вы настроите его правильно.

0 голосов
/ 08 августа 2011

Зависит от того, что делают эти методы, поэтому решения могут быть разными.Но если эти методы как-то логически не связаны друг с другом, я бы предложил абстрагировать каждый метод с помощью интерфейса, подобного

    interface ILogicBAware
    {
      void DoB();
    }

    interface ILogicCAware
    {
      void DoC();
    }

    interface IAllMethods : ILogicBAware, ILogicCAware
    {
       void DoAll();
    }

Таким образом, вы получаете большую гибкость и меньшую связь.Таким образом, вы можете двигаться вперед и решить, как будет реализована актуальная логика.Но опять же, это зависит от того, что находится под капотом классов и методов, которые вы предоставили ...

...