2008-09-29 5 views
2

Я создал свою собственную реализацию дерева для various reasons и придумал два класса - «базовый» класс, который является общим узлом дерева, который заполнен логикой и другим классом, который расширяет ту, которая является более специализированной.Возможно ли, чтобы объекты «перехватывали» объекты в базовых классах?

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

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

Проблема может быть сводились к следующему:

public class Foo { 
    public String value() { return "foo"; } 

    public Foo doStuff() { 
     // Logic logic logic.. 
     return new Foo(); 
    } 
} 

class Bar extends Foo { 
    public String value() { return "bar"; } 
} 

new Bar().doStuff().value(); // returns 'foo', we want 'bar' 

Первое, что пришло мне в голову бы иметь «создать крюк», которые расширяют классы могли переопределять:

public Foo createFooHook(/* required parameters */) { 
    return new Foo(); 
} 

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

Это как приготовление пищи в то время как голый - он чувствует себя опасным и не нужен.

Итак, как бы вы справились с этой ситуацией?

ответ

3

Итак, получив мою копию Design Patterns и открыв ее, я уверен, что это первый раз, когда я обнаружил, что хочу.

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

Это может быть исправлено с некоторым рефакторинга, хотя, и я в конечном итоге с чем-то эффект:

abstract class AbstractFoo { 
    public String value() { return "Foo"; } 

    public AbstractFoo doStuff() { 
     // Logic logic logic 
     return hook(); 
    } 

    protected abstract AbstractFoo hook(); 
} 

class Foo extends AbstractFoo { 
    protected AbstractFoo hook() { return new Foo(); } 
} 

class Bar extends AbstractFoo { 
    public String value() { return "Bar"; } 

    protected AbstractFoo hook() { return new Bar(); } 
} 

new Bar().doStuff().value(); // Returns 'Bar'! 
+0

Я хотел бы дать другое имя метода крюк(), например createObjec() или createFooInstance(). – 2008-09-29 09:53:45

0

Я не думаю, что есть лучший подход. Просто будьте осторожны, чтобы не называть эти крючки от конструктора.

1

В дополнение к шаблону Factory, я бы принять взглянуть на композитный шаблон - он, как правило, хорошо подходит для работы с Фабрикой в ​​древовидных ситуациях.

Composite Design Pattern