Вопрос о модели делегирования (или ооо) - PullRequest
1 голос
/ 24 июня 2011

У меня есть вопрос, касающийся принципа делегирования в ООП.Я буду использовать пример классов Window & Rectangle из книги шаблонов проектирования GOF для объяснения моего запроса.

public class Window
{
    Rectangle myDelegate;

    public void Area()
    {
        return myDelegate.Area();
    }
}

public class Rectangle
{
    public int Area()
    {
        return 2*3;
    }
}

Мой вопрос: может ли Rectangle (делегат) иметь ссылку на окно (родительский класс)).то есть:

public class Window
{
    Rectangle myDelegate;
    public int myArea;

    public void Area()
    {
        myDelegate.Area();
    }
}

public class Rectangle
{
    Window myParent;

    public void Area()
    {
        myParent.myArea = 2 * 3;
    }
}

В нетривиальных случаях вышеприведенное сделает делегату гораздо удобнее обновить состояние родителя.Это логично или я что-то здесь упускаю?

Спасибо!

Ответы [ 3 ]

1 голос
/ 24 июня 2011

Гораздо проще поддерживать однонаправленные ссылки.В этом случае было бы целесообразно, чтобы Window запросил прямоугольник своих собственных измерений и использовал его для выделения необходимого пространства.Тогда у Rectangle будет свобода отображать себя в своем пространстве так, как он хочет.

0 голосов
/ 25 июня 2011

Если бы это были мои классы, и мне нужно, чтобы делегат общался с родителем, я бы создал событие для делегата и настроил бы родителя в качестве слушателя.Это имеет несколько преимуществ:

  • Позволяет разделить один и тот же делегат между несколькими родителями.Это может быть полезно, если делегат представляет конечный ресурс («порт 1234») или если делегат дорог в создании экземпляра.
  • Родитель может контролировать, заботится ли он о поведении делегата или нет.Не волнует?Не регистрируйте интерес к событию.
  • Меньше соображений по обслуживанию (как Борис указал выше)
0 голосов
/ 24 июня 2011
public interface IShape
{
  void Area();
  void SetArea(int area);
}

public class Window : IShape
{
   private IShape rectangle;
   private int myArea;

   public Window(IShape shape)
   {
      rectangle = shape;
   }

   public void SetArea(int area)
   {
      myArea = area;
   }
   public void Area()
   {
      rectangle.Area();
   }
}

public class Rectangle : IShape
{
   private IShape window;

   public Rectangle(IShape shape)
   {
       window = shape;
   }

   public void Area()
   {
      SetArea(2 * 3);
   }

   public void SetArea(int area)
   {
       window.SetArea(area);
   }
}

...