Разработка класса таким образом, чтобы он не стал «объектом Бога» - PullRequest
5 голосов
/ 07 апреля 2010

Я разрабатываю приложение, которое позволит мне рисовать некоторые функции на графике. Каждая функция будет нарисована из набора точек, которые я передам этому графическому классу.

Существуют различные виды точек, все они наследуются от класса MyPoint. Для каких-то точек это будет просто выводить их на экран такими, какие они есть, другие можно игнорировать, другие добавлять, поэтому с ними связана какая-то логика, которая может стать сложной.

Как на самом деле рисовать графику здесь не главное. Меня беспокоит то, как сделать кодовую логику такой, чтобы этот класс GraphicMaker не стал так называемым God-Object.

Было бы легко сделать что-то вроде этого:

class GraphicMaker {
    ArrayList<Point> points = new ArrayList<Point>();

    public void AddPoint(Point point) {
        points.add(point);
    }

    public void DoDrawing() {
        foreach (Point point in points) {
            if (point is PointA) {
                //some logic here
            else if (point is PointXYZ) {
                //...etc
            }
        }
    }
}

Как бы вы сделали что-то подобное? У меня есть ощущение, что правильным способом было бы поместить логику рисования в каждый объект Point (чтобы каждый дочерний класс из Point знал бы, как рисовать сам), но возникают две проблемы:

  1. Будут виды точек, которые должны знать все другие точки, существующие в классе GraphicObject, чтобы уметь рисовать себя.
  2. Я могу сделать многие методы / свойства из класса Graphic общедоступными, чтобы все точки имели ссылку на класс Graphic и могли делать всю свою логику по своему усмотрению, но не слишком ли это большая цена для платить за нежелание иметь класс Бога?

Ответы [ 2 ]

4 голосов
/ 07 апреля 2010

Я бы сделал так, как вы предложили, и сделал бы каждую точку ответственной за рисование, передавая ей массив других точек:

interface ICanDraw {
    void Draw(ArrayList<Point> allPoints);
}

public abstract class Point : ICanDraw {
    ...
}

public PoniePoint : Point {
    public void Draw(ArrayList<Point> allPoints) {
        // do drawing logic here
    }
}

Для вашего GraphicMaker:

public void DoDrawing() {
    foreach (Point point in points) {
        point.Draw(points);
    }
}

(Моя Java немного ржавая, так что она не может на 100% синтаксически исправить Java, но я думаю, что это передает мое предложение).

3 голосов
/ 07 апреля 2010

Вы правы, что каждый подкласс Point должен иметь свой собственный метод рисования, переопределяющий метод в базовом классе Point.

Метод рисования должен принимать ссылку на графический объект, который должен иметь открытые методы / свойства для всего, что необходимо использовать в методах рисования точек, включая список точек, если это одна из вещей.некоторые методы рисования нужны.

Почему вы беспокоитесь о том, чтобы делать открытые методы в классе графики?По мере роста кода несколько дополнительных видимых методов будут намного менее запутанными, чем один огромный метод, который делает все.

...