3

Java の演習として Mysql データベースをモデリングしています。個人実験。また、テーブルの照合順序を文字列として保存したいのですが、列とテーブルの照合順序が異なる可能性があるため、列ごとにそれを保存する必要があります。列の照合フィールドがテーブルの照合フィールドを指すだけであれば、非常に役立ちます。しかし、Java にはポインターがないことはわかっています。

2 つのオブジェクトが常に一致するように、あるオブジェクトのフィールドを別のオブジェクトのフィールドに向ける方法を教えてください。

4

4 に答える 4

6

Java には参照があります。これは、ポインター計算を行う機能を持たないポインターの優れた部分です。

public class Table {

  // name does not store a String, it stores a reference to a String
  private String name;

  // tableName is not passed in by copy, tableName's reference is passed in.
  public Table(String tableName) {
    // this is not a copy assignment, but a reference assignment
    name = tableName;
  }

}

Java で常にフィールドを指す限り、いくつかのことを覚えておく必要があります。オブジェクトはオブジェクト指向プログラミング言語の基本要素であり、名前ではありません。そのため、オブジェクトの内部名への参照を構築することはできません。これは、オブジェクトをその基本型で参照しているのか、スーパー型で参照しているのかがはっきりしないためです。スーパークラスとサブクラスの両方に同一の名前が存在する可能性があるため (スーパークラスの型が隠される可能性があります)、フィールド名の参照は、それらが解決される実際のクラス インスタンスを知らなければ正しく解決できません。

これは意図的なものであり、偶然ではありません。実際、呼び出し元とデータの間にコードを挿入できる「シム」がないため、クラスのメンバー フィールドの外部知識がまさにコード メンテナンスを非常に困難にしています。データをカプセル化する (メソッド呼び出しの背後に置く) ことにより、将来のコード保守の準備が整います。なぜなら、変更される可能性のある内部データ要素に基づいて戻り値を生成するコードを挿入できるからです。

public class Table {

  public Column[] columns;

  public String name;

  public Table() {
    name = ...;
    columns = ...;
  }

}

public class CreateTableDDL {

  public String statement(Table table) {
    StringBuilder buffer = new StringBuilder();
    buffer.append("CREATE TABLE ");
    buffer.append(table.name);
    buffer.append(" (");
    for (int i = 0; i < table.columns.length; i++) {
      Column column = table.columns[i];
      ...
    }
    ...
    return buffer.toString();
  }

}

これは必ずしも悪いことではありませんが、新しい nifty で s を動的columnsに追加または削除できるように、それをofColumnにしたいと判断するまでは、必ずしも悪いことではありません。ListColumnColumnTableEditor

基本データ要素を公開したので、コード ベース全体を検索してフィールドの使用を見つけ、インターフェイスを使用するようにすべての使用を書き直す必要がありListます。実際には、フィールドを直接使用した可能性のあるすべての外部ライブラリも検索する必要があるため、それ以上のことを行う必要があります。未知の複数の JAR がこのパブリック クラスを使用している可能性があるからです。columns

さらに、私たちが行っていることのほとんどは、columns実際にはTableのビジネスであることがすぐにわかりますが、「ヘルパー」と補助クラスにあり、表で最もよくローカライズされた責任を損なうものです。

最後に、外部クラスがテーブルの知識なしにテーブルの列を変更していることに気付くかもしれません。なぜなら、データを直接取得することによって、テーブルに変更を警告する可能性のあるコードをバイパスするからです。

単純にやった場合

public class Table {

  private Column[] columns;

  private String name;

  public Table() {
    name = ...;
    columns = ...;
  }

  public Column[] getColumns() {
    Column[] copy = new Column[columns.length];
    for (int i = 0; i < columns.length; i++) {
      copy[i] = columns[i].clone();
    }
    return copy;
  }

}

次に、基本ストレージを に簡単に変換Listし、リストから「後方互換性のある」列の配列を構築することができました。以前の既存columnsフィールドがMap of String to DataType.

 public class CreateTableDDL {

  public String statement(Table table) {
    StringBuilder buffer = new StringBuilder();
    buffer.append("CREATE TABLE ");
    buffer.append(table.getName());
    buffer.append(" (");
    for (int i = 0; i < table.getColumns().length; i++) {
      Column column = table.getColumn(i);
      ...
    }
    ...
    return buffer.toString();
  }

}
于 2012-06-14T19:38:16.283 に答える
1

Java 変数は参照によって渡されます。したがって、 を宣言しObject objた場合は、obj常に現在のスコープ内の同じオブジェクトへの参照になります。メソッドに渡すときobjは、オブジェクトのコピーではなく、オブジェクトへの参照を渡します。

さらに、Java にはIterableインターフェイスを実装するコレクション用の Iterator もあります。Listこれらは aまたは類似の特定の位置へのポインターのように機能します。

于 2012-06-14T19:42:00.450 に答える
0

可能なすべての照合タイプのリストを持つ Enum を作成し、collat​​ionType というメンバー/プロパティを Table クラスと Column クラスに追加し、同じ Enum メンバーを同じオブジェクトに割り当てます。

于 2012-06-14T19:42:38.403 に答える