4

私は JDBC を使用しており、多くのクラスには次のような内部 RowMapper クラスがあります。

public class Foo {
  class AppleRows implements RowMapper<Apple> {
    public Apple mapRow(ResultSet rs, int rowNum) throws SQLException {
      Apple a = new Apple();
      a.setName(rs.getString("Name"));
    }
  }

  class AppleRowsJoinedWithSomethingElse implements RowMapper<Apple> {
    public Apple mapRow(ResultSet rs, int rowNum) throws SQLException {
      Apple a = new Apple();   
      a.setName(rs.getString("Name"));
      a.setSomethingElse(rs.getString("SomethingElse"));
    } 
  }
}

上記の例では、行a.setName(rs.getString("Name"))が複製されています。これは単なる例ですが、私の実際のコードでは、このようなフィールドが 10 個以上あります。これを行うためのより良い方法があるかどうか疑問に思っていますか?

注:結果を別のテーブルと結合する(より多くのフィールドを取得する)いくつかの場所からそれらを使用しているため、別のマッパーが必要です。

4

4 に答える 4

2

extend+ 使用できますsuper.mapRow()...

public class Foo {
  class AppleRows implements RowMapper<Apple> {
    public Apple mapRow(ResultSet rs, int rowNum) throws SQLException {
      Apple a = new Apple();
      a.setName(rs.getString("Name"));
      return a;
    }
  }

  class AppleRowsJoinedWithSomethingElse extends AppleRows {
    public Apple mapRow(ResultSet rs, int rowNum) throws SQLException {
      Apple a = super.mapRow(rs, rowNum);
      a.setSomethingElse(rs.getString("SomethingElse"));
      return a;
    } 
  }
}

または、コードの再利用のメカニズムとして継承を使用したくない場合は、単に委任します。

public class Foo {
  class AppleRows implements RowMapper<Apple> {
    public Apple mapRow(ResultSet rs, int rowNum) throws SQLException {
      Apple a = new Apple();
      a.setName(rs.getString("Name"));
      return a;
    }
  }

  class AppleRowsJoinedWithSomethingElse implements RowMapper<Apple> {
    public Apple mapRow(ResultSet rs, int rowNum) throws SQLException {
      Apple a = new AppleRows().mapRow(rs, rowNum);
      a.setSomethingElse(rs.getString("SomethingElse"));
      return a;
    } 
  }
}
于 2013-04-02T19:09:44.530 に答える
0

各マッパーは、単一の行定義をマップします。これを DRY の違反とは言いません。

の基本ビューで 1 つの列名が変更された場合、AppleRowsJoinedWithSomethingElse変更する必要があるのは 1 か所だけです。

一般的なコードを使用してこれをリファクタリングすると、提供するビューAppleRowsJoinedWithSomethingElseが変更されても、基になるビューが変更されない場合、奇妙な立場になりますAppleRows

于 2013-04-02T19:12:00.617 に答える
0

共通の機能を共有するために拡張する必要はありません。これを入力しているだけなので、実際にはコンパイルされない可能性があります。

public class CommonBlammy
{
    private CommonBlammy() { } // private constructor to prevent instantiation.

    public static Apple mapRow(final ResultSet resultSet)
    throws SQLException
    {
        Apple returnValue = new Apple();

        returnValue.setName(resultSet.getString("Name"));

        return returnValue;
    }
}

public class AppleRows implements RowMapper
{
    public Apple mapRow(
        final ResultSet resultSet,
        final int rowNumber)
        throws SQLException
    {
      return CommonBlammy.mapRow(ResultSet resultSet);
    }
}

public class AppleRowsJoinedWithSomethingElse implements RowMapper
{
    public Apple mapRow(
        final ResultSet resultSet,
        final int rowNumber)
    throws SQLException
    {
        Apple returnValue;

        returnValue = CommonBlammy.mapRow(ResultSet resultSet);
        returnValue.setSomethingElse(rs.getString("SomethingElse"));

        return returnValue;
    } 
}
于 2013-04-02T19:36:34.567 に答える
0

これを行う 1 つの可能な方法は、継承を使用することです。特に、内部クラスをstaticネストされたクラスにすることができる場合は、次のようになります。

public class Foo {
  static class AppleRows implements RowMapper<Apple> {
    public Apple mapRow(ResultSet rs, int rowNum) throws SQLException {
      Apple a = new Apple();
      a.setName(rs.getString("Name"));
      return a;
    }
  }

  static class AppleRowsJoinedWithSomethingElse extends AppleRows {
    public Apple mapRow(ResultSet rs, int rowNum) throws SQLException {
      Apple a = super.mapRow(rs, rowNum);
      a.setSomethingElse(rs.getString("SomethingElse"));
      return a;
    } 
  }
}

ここでネストされたクラスを使用した理由は、 (少なくとも現在の実装では) 使用されていないネストされていstaticないクラスに含まれるクラスのインスタンスへの暗黙的な参照があるためです。static

于 2013-04-02T19:09:46.783 に答える