4

私は2つのインターフェースを持っていますQueryFilter単純Query化のための例のクラスです。今のところ1つのクエリがあります)、実際のフィルターに応じて関数を書きたいと思います。Query.applyFilter()つまりNameFilter、および他DateFilterすべてのフィルターの異なる関数です。

私の解決策は次のとおりです。

interface Filter {
    public abstract void modifyQuery(Query query);
};

class NameFilter implements Filter{
    public void modifyQuery(Query query){
        query.applyFilter(this);
    }
};

class DateFilter implements Filter{
    public void modifyQuery(Query query){
        query.applyFilter(this);
    }
};

class Query {
    public void applyFilter(Filter filter){
        filter.modifyQuery(this);
    }

    void applyFilter(NameFilter* filter) {
        //"applying NameFilter";
    }

    void applyFilter(DateFilter* filter) {
       //apply dateFilter
   }
}

それでは、ここmodifyQuery()ですべての Filter クラスの実装を書き直す必要があります。

次に、C ++でそれを回避する方法があります:テンプレートを使用してキャストしmodifyQuery()ます:

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <vector>

using namespace std;

class Query;

class IFilter
{
public:
  virtual void modifyQuery(Query* query) = 0;
};

template <typename T>
class Filter : public IFilter
{
public:
  virtual void modifyQuery(Query* query);
};

class DateFilter;
class NameFilter;

class Query
{
public:

  void applyFilter(IFilter* filter)
  {
    cout << "applying Filter" << endl;
    filter->modifyQuery(this);
  }

  void applyFilter(NameFilter* filter)
  {
    cout << "applying NameFilter" << endl;
  }

  void applyFilter(DateFilter* filter)
  {
    cout << "applying DateFilter" << endl;
  }
};

template <typename T>
void Filter<T>::modifyQuery(Query* query)
{
  query->applyFilter(dynamic_cast<T*> (this));
}

class DateFilter : public Filter<DateFilter>
{
};

class NameFilter : public Filter<NameFilter>
{
};

int main()
{
  Query* query = new Query();
  IFilter* nameFilter = new NameFilter();
  IFilter* dateFilter = new DateFilter();

  std::vector<IFilter*> filterList;
  filterList.push_back(nameFilter);
  filterList.push_back(dateFilter);

  for (int i = 0; i < 2; ++i)
  {
    query->applyFilter(filterList[i]);
  }
  return 0;
}

デモ

しかし、ジェネリックはテンプレートと同じように動作しないため、Java でこのソリューションを使用することはできません。コピーと貼り付けを避けるために Java で使用できるものは何ですか?

4

2 に答える 2

1

提案:

interface Filter {
    public abstract void modifyQuery(Query query);
};

class NameFilter implements Filter{
    public void modifyQuery(Query query){
        // Modify query based on "Name"...
    }
};

class DateFilter implements Filter{
    public void modifyQuery(Query query){
        // Modify query based on "Date"...
    }
};

class Query {
    public void applyFilter(Filter filter){
        filter.modifyQuery(this);
    }

    // No need for other applyFilter() methods - all filters are instances of Filter.
}
于 2012-12-25T20:11:38.403 に答える