Есть ли конкретный способ дать определенному подклассу некоторые функции суперкласса? - PullRequest
7 голосов
/ 03 июля 2019

Проблема

Я пытаюсь создать приложение, в котором класс объектов может реализовывать некоторые операции из общего пула доступных операций.Конечная цель - не допускать дублирования кода и максимально соблюдать законы ООП.

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

Первые мысли

Я думал о реализации чего-то близкого к Composite pattern,
как описано 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 shouldn 'не может выполнять поиск по категориям, но может
выполнять операции поиска по фразам и termSearch.Соответственно, TipIndex класс
должен иметь возможность выполнять некоторые методы родительского класса.

Заключительные мысли

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

PS Если вы думаете, что шаблон Composite - это путь, каким образом вы фактически добавите примитивные объекты в составной класс и каким образомВы вызываете их, когда это необходимо?

Ответы [ 3 ]

1 голос
/ 03 июля 2019

Все методы, определенные в суперклассе, доступны при получении классов, но с 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, которые предоставляют данные и выполняют реализацию в абстрактном классе, но могут предоставить доступ к внутренним вещам, поскольку все объявленные методы в интерфейсе являются общедоступными.

1 голос
/ 03 июля 2019

Если вы не хотите использовать 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/");
    }
}
0 голосов
/ 03 июля 2019

Вы можете использовать шаблон Composite, если вам нужно иметь те же объекты и использовать их, как вы хотите в ваших классах ReviewIndex и TipIndex. вы можете использовать список, который подразумевает агрегацию, и вы можете использовать один экземпляр каждого объекта (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

и мы использовали один и тот же CategorySearch, TermSearch и PhraseSearch для классов ReviewIndex и TipIndex.

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