0

这是场景。

public interface Processor{

    public void create();

    public void setDocuments();

    public abstract void prepareDocuments();

}

public class ProcessorImpl implements Processor{

    public void create(){
        // Do something
    }

    public void setDocuments(){
       // Do something
    }

}

public class ProcessorA implements ProcessorImpl{
    // this class will implement only once abstract 
    // method which is prepareDocuments()

    public void prepareDocuments(){
       // prepare documents..and also 
       // set the Documents list which will be checked by create() 
       // method and then index will be created.

    }

}


public class IndexGenerator{

    public static void main( String[] args){

       ProcessorA a = new ProcessorAImpl();
       a.create();  
    }
}

简要背景......我正在开发一个通用框架来处理所有与 Lucene 索引相关的活动,包括创建索引、从索引中删除文档、更新和添加到索引中。除了创建文档之外,处理索引的所有逻辑都保持不变。每个索引都有不同类型的文档,因此我保留了 prepareDocuments() 方法的抽象,并为每个索引类型实现了它。

现在我想让所有索引生成器类简单地创建其特定索引处理器的实例,如 ProcessorA 并调用 create() 方法。但问题是 create() 方法总是发现文档列表为空/空,尽管 prepareDocuments 通过调用 setDocuments() 方法来设置文档。我知道存在一些设计缺陷,我真的需要向 OO 专家寻求帮助。

谢谢热心

4

2 回答 2

1

我不知道为什么你会得到空/null,因为没有足够的代码可以从中推断出来。但是,对于您的问题,我会使用模板方法设计模式,例如在这里描述:http ://en.wikipedia.org/wiki/Template_method_pattern

我认为这就是你想要做的。

顺便提一句。implements关键字仅用于接口。您尝试使用它而不是在extends这里:

public class ProcessorA implements ProcessorImpl
于 2012-04-23T06:11:58.823 回答
0

为了详细说明先前关于模板的答案(我完全同意),听起来您可能对调用 setDocuments() 的顺序有疑问。模板方法模式的好处之一是强制调用不同方法(抽象或非抽象)的顺序。

您可以考虑像这样重组基类:

public interface Processor {
    ...
    // This method orchestrates doc preparation by ensuring the correct
    // ordering of method invocation, and calls the derived class impl
    // method doPrepareDocuments()
    public void prepareDocuments() {
        // do document creation stuff here by calling
        // appropriate methods (abstract or not)

        setDocuments();

        // implemented in derived classes to do specific document preparations
        doPrepareDocuments();
    }

    public abstract void doPrepareDocuments();
    ...
}

这样,每个派生类实现都不必记住要采取的所有步骤,以及按照什么顺序执行,而是专注于它知道的内容。这种方法增加了凝聚力。

于 2012-04-23T10:32:54.810 回答