Каков правильный дизайн ОО для максимального повторного использования и эффективности? - PullRequest
1 голос
/ 08 апреля 2011

Предположим, у меня есть пакет Java (и .jar, и исходные коды).Вот определения того, что некоторые из классов я хотел бы использовать повторно.

abstract class Tree {
  public abstract Tree[] children();
  public void print();
}

class LabeledTree extends Tree implements Label {
  Label label;
  Tree[] daughterChildren;
  public Tree[] children();
}

class Demo {
  public static void main(String[] args) {
    Parser p = new Parser();
    String[] sent = { "This", "is", "an", "easy", "sentence", "." };
    Tree parse = p.apply(sent);
    parse.print();
  }
}

Приведенный выше метод apply возвращает LabeledTree.Теперь я хотел бы создать свой собственный тип дерева, скажем MyTree, который имеет следующую структуру:

class MyTree {
  int value;
  Label label;
  public void myPrint();
}

Где вы предлагаете мне поместить этот класс в дерево наследования, чтобы я могнапрямую создавать экземпляры объектов этого класса из метода apply?Как вы думаете, я должен был спроектировать свою систему для максимального повторного использования программного обеспечения и не нужно анализировать каждое дерево для построения объектов MyTree?

Ответы [ 3 ]

5 голосов
/ 08 апреля 2011

Несколько комментариев:

Прежде всего, ваше определение дерева раскрывает важную деталь - каждый объект дерева является узлом. Это создает целую кучу концептуальных единиц. В реальном API у вас будет интерфейс Tree и реализация, использующая узлы. Все члены данных будут находиться в узле, кроме корневого узла, который будет в вашем TreeImpl.

Во-вторых, я твердо верю в то, что присвоение имен является важным первым шагом к созданию хорошего и читабельного кода, и это часто влияет на качество вашего ОО-дизайна. Дерево не должно просто реализовывать метку. Вы можете сказать: «Дерево - это ярлык»? С другой стороны, если у вас было что-то вроде: «TreeNode реализует HasLabel», было бы яснее - «у вашего узла дерева есть метка».

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

1 голос
/ 08 апреля 2011

Я согласен с @Uri, что создание Tree как интерфейса вместо абстрактного класса было бы улучшением.

Если ваш синтаксический анализатор не знает о подклассах Tree, тогда одним из способов является схема на основе отражения, использующаяClass.forName.Другим способом решения этой проблемы было бы использование системы, в которой расширение расширений регистрируется, когда они установлены (пример здесь - реестр плагинов Eclipse, хотя это очень сложный пример этого шаблона).

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

Языковые процессоры программирования на Java: компиляторы и интерпретаторы Дэвид Уотт (автор), Дерик Браун (автор)

Он доступен на Amazon и полезенначинает понимать, как проектировать парсеры языка.Все примеры на Java.

Кроме того, если у вас есть грамматика, вы можете попробовать запустить ее через Antlr и посмотреть на выходные данные, чтобы найти хорошие примеры организации парсера.

http://www.antlr.org/

0 голосов
/ 08 апреля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...