我正在尝试创建一个对象类可以实现某些功能的应用程序 可用操作总池中的操作。最终目标是不重复任何代码,并尽可能遵守OOP的法律。
更详细地讲,我正在尝试使用Lucene创建一个搜索引擎。露西恩
使用许多索引。我已经实现了一个简单的结构,其中不同的索引对象继承了父类的方法。问题是,无论在该父类中实现什么方法,它都会自动变为可供所有子类使用。我想让用户选择该选项,以确定他是否要进行短语搜索,术语搜索或该特定索引可用的任何其他操作。问题是,例如某些索引不应具有进行短语搜索的选项。
我已经考虑过实现类似于 Composite 模式的内容,
如GoF所述。我会将搜索操作(例如术语搜索,词组搜索)实现为实现某些 Component 类的原始操作,然后将这些原始对象添加到 Composite 对象中。 Composite 对象将实现与原始对象相同的 Component 类。
public abstract class Index {
public Index(String indexPath) {
// Constructor using the information provided by the subclass
}
public void phraseSearch(...) {
// Do the operation
}
public void termSearch(...) {
// Do the operation
}
public void categorySearch(...) {
// Do the operation
}
}
public class ReviewIndex extends Index {
public ReviewIndex() {
super("./review_index/");
}
}
public class TipIndex extends Index {
public TipIndex() {
super("./tip_index/");
}
}
类ReviewIndex
不能执行categorySearch而是应该
能够执行phraseSearch和termSearch。分别是TipIndex
类
应该能够执行某些父类方法。
我知道我的解决方案中没有代码重复,但是有 每次创建新索引对象时都会生成无用的方法。 预先谢谢大家!
P.S。如果您认为 Composite 模式是可行的方式,那么您将以哪种方式将原始对象实际添加到Composite类中,并在需要时以哪种方式调用它们?
答案 0 :(得分:1)
如果您不想为categorySearch(...)
类使用ReviewIndex
,请在保留categorySearch(...)
方法的地方再创建一个层次结构。
示例:
public abstract class Index {
public Index(String indexPath) {
// Constructor using the information provided by the subclass
}
public void phraseSearch(...) {
// Do the operation
}
}
// Give a meaningful Name
public abstract class IndexChild1 extends Index {
public void categorySearch(...) {
// Do the operation
}
}
// Give a meaningful Name
public abstract class IndexChild2 extends Index {
public void termSearch(...) {
// Do the operation
}
}
public class ReviewIndex extends IndexChild1 {
public ReviewIndex() {
super("./review_index/");
}
}
public class TipIndex extends IndexChild2 {
public TipIndex() {
super("./review_index/");
}
}
答案 1 :(得分:1)
在超类中定义的所有方法在派生类中都可用,但是使用Java 8,您可以通过在接口中使用默认方法来获得类似的信息。因此,代替一个包含所有可能方法的抽象类,您可以实现四个接口
public interface Searchable {
public String getIndexPath();
}
public interface PhraseSearchable extends Searchable {
public default void phraseSearch() {
String indexPath = getIndexPath();
// do the search
}
}
public interface TermSearchable extends Searchable {
public default void termSearch() {
String indexPath = getIndexPath();
// do the search
}
}
public interface CategorySearchable extends Searchable {
public default void categorySearch() {
String indexPath = getIndexPath();
// do the search
}
}
为避免重复的代码,您可以创建一个抽象类
public abstract class AbstractSearchable implements Searchable {
private String indexPath;
public AbstractSearchable(String indexPath) {
this.indexPath = indexPath;
}
// other methods that might be useful
}
然后您的实际类可以实现相应的接口
public class ReviewIndex extends AbstractSearchable implements CategorySearchable {
public ReviewIndex() {
super("./review_index/");
}
}
public class TipIndex extends AbstractSearchable implements PhraseSearchable, TermSearchable {
public ReviewIndex() {
super("./review_index/");
}
}
是否可能在很大程度上取决于搜索方法的实际实现。接口不能包含任何成员等,因此这些方法必须能够自行运行(就像静态方法,而无需使用类的任何静态成员)。您可以通过在Searchable
接口中添加更多方法来解决此问题,这些方法提供数据并在抽象类中执行实现,但是由于接口中所有已声明的方法都是公共的,因此可能会将内部内容公开给公众。
答案 2 :(得分:0)
如果需要具有相同的对象并根据需要在ReviewIndex和TipIndex类中使用它们,则可以使用Composite模式。您可以使用一个表示聚合的列表,并且可以按任意顺序对每个对象(PhraseSeach,TermSearch,CategorySearch)使用一个实例化。 这是代码:
import java.util.ArrayList;
import java.util.List;
public class Main{
public static void main(String[] args) {
Main m = new Main();
m.run();
}
public void run() {
ReviewIndex ri = new ReviewIndex();
}
public interface ISearch {
public void search();
}
public class SearchComposite implements ISearch{
private List<ISearch> l = new ArrayList<ISearch>();
public SearchComposite(String index) {
System.out.println(index);
}
public int addSearch(ISearch search) {
l.add(search);
return this.l.size() - 1;
}
public List<ISearch> getSearch(){
return this.l;
}
public void search() {
System.out.println("search");
}
}
public class CategorySearch implements ISearch{
@Override
public void search() {
System.out.println("category search");
}
}
public class PhraseSearch implements ISearch{
@Override
public void search() {
System.out.println("phrase search");
}
}
public class TermSearch implements ISearch{
@Override
public void search() {
System.out.println("term search");
}
}
CategorySearch cs = new CategorySearch();
TermSearch ts = new TermSearch();
PhraseSearch ps = new PhraseSearch();
public class ReviewIndex {
SearchComposite sc = new SearchComposite("./review_index/");
public ReviewIndex() {
int p = sc.addSearch(ps);
int t = sc.addSearch(ts);
sc.search();
List<ISearch> s = sc.getSearch();
s.get(p).search();
s.get(t).search();
}
}
public class TipIndex {
SearchComposite sc = new SearchComposite("./tip_index/");
public TipIndex() {
int p = sc.addSearch(ps);
int t = sc.addSearch(ts);
int c = sc.addSearch(cs);
sc.search();
List<ISearch> s = sc.getSearch();
s.get(p).search();
s.get(t).search();
s.get(c).search();
}
}
}
上面的代码输出为:
./review_index/
search
phrase search
term search
并且我们对ReviewIndex和TipIndex类使用了相同的CategorySearch,TermSearch和PhraseSearch。