- PR -

基本クラスが同じ違うクラスを一つのクラスで使い分ける方法

投稿者投稿内容
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-03-06 11:17
引用:

iStationさんの書き込み (2006-03-04 22:20) より:
引用:

R・田中一郎さんの書き込み (2006-03-03 20:18) より:
...
コード:
class 商品マスター : 編集クラス {
    public 商品マスター { // コンストラクタ
        this.レコード = 商品マスターレコード操作;
    }
}
class 社員マスター : 編集クラス {
    public 社員マスター { // コンストラクタ
        this.レコード = 社員マスターレコード操作;
    }
}
class 取引先マスター : 編集クラス {
    public 取引先マスター { // コンストラクタ
        this.レコード = 取引先マスターレコード操作;
    }
}


...



コード:
class 商品マスター {
    public 商品マスター { // コンストラクタ
        this.レコード = new 編集クラス(this);
    }
}
class 社員マスター {
    public 社員マスター { // コンストラクタ
        this.レコード = new 編集クラス(this);
    }
}
class 取引先マスター {
    public 取引先マスター { // コンストラクタ
        this.レコード = new 編集クラス(this);
    }
}


こんな感じでは駄目でしょうか?




サンプルをありがとうございました。
実は、この方法を試そうとコードを変更し始めたのですが、更新開始時にトランザ
クションを開始して、更新終了時にコミットしているので、よくよく考えてみたら
コンストラクタでインスタンスを渡す方法では駄目でした。

今回は、メソッドに抽出する方向でいこうと思います。
ありがとうございました。
vincent
大ベテラン
会議室デビュー日: 2004/07/09
投稿数: 142
投稿日時: 2006-03-06 12:32
GoFのTemplate Method風味でこういうのはどうでしょうか。
※細かいコードは省略しています

コード:

abstract class 更新テーブル
{
 //公開メソッド
public sealed void Insert() { ExecuteUpdate(GetInsertQuery()); }
public sealed void Update() { ExecuteUpdate(GetUpdateQuery()); }
public sealed void Delete() { ExecuteUpdate(GetDeleteQuery()); }

 //共通トランザクション
 private sealed void ExecuteUpdate(string query) {

  if (HasError) return;
  try {
   command.CommandText = query;
   command.ExecuteNonQuery();
   transaction.Commit();
  } catch (Exception ex) {
   transaction.Rollback();
  }
 }

 //サブクラスで実装してもらうものシリーズ
 protected virtual string GetInsertQuery() {}
 protected virtual string GetUpdateQuery() {}
 protected virtual string GetDeleteQuery() {}
 protected bool HasError { get; }

}

class 商品マスタ: 更新テーブル {

 //各フィールドはプロパティで取得・設定
 public int 番号;

 //妥当性検証
 protected bool HasError {
  get { return 妥当性継承ロジックの結果;}
 }

 //テーブルごとのクエリ生成(insert, deleteも同様)
 protected override string GetUpdateQuery() {
  return "Update 商品マスタ SET 番号 = " + this.番号 + ...
}
}


使い方はこんな感じで。
コード:

商品マスタ a = new 商品マスタ();
a.番号 = 200;
a.Update();



[ メッセージ編集済み 編集者: vincent 編集日時 2006-03-06 12:34 ]
vincent
大ベテラン
会議室デビュー日: 2004/07/09
投稿数: 142
投稿日時: 2006-03-06 13:21
先程は単発でトランザクションが完結する例を紹介しましたが、
3つのテーブル全体をまたがってトランザクションの対象にするのなら、

商品マスタa = new 商品マスタ();
取引先マスタ b = new 取引先マスタ();
社員マスタ c = new 社員マスタ();

List<更新テーブル> txList = new List<更新テーブル>();
txList .add(a);
txList .add(b);
txList .add(c);

try {
 foreach(更新テーブル t in txList ) {
  t.Update();
 }
 transaction.Commit();
} catch(Exception ex) {
 transaction.Rollback();
}
のように書くことで統一的に更新できます。

insert, update, deleteの混在したトランザクションの場合は
サブクラスのほうでモード指定すればいいと思います。
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-03-06 14:48
引用:

vincentさんの書き込み (2006-03-06 12:32) より:

GoFのTemplate Method風味でこういうのはどうでしょうか。



これは良いですね!
このやり方で書き直してみます。ありがとうございました。
iStation
大ベテラン
会議室デビュー日: 2003/12/08
投稿数: 158
投稿日時: 2006-03-06 22:10
引用:

引用:

コード:

class 商品マスター {
public 商品マスター { // コンストラクタ
this.レコード = new 編集クラス(this);
}
}
class 社員マスター {
public 社員マスター { // コンストラクタ
this.レコード = new 編集クラス(this);
}
}
class 取引先マスター {
public 取引先マスター { // コンストラクタ
this.レコード = new 編集クラス(this);
}
}


こんな感じでは駄目でしょうか?




サンプルをありがとうございました。
実は、この方法を試そうとコードを変更し始めたのですが、更新開始時にトランザ
クションを開始して、更新終了時にコミットしているので、よくよく考えてみたら
コンストラクタでインスタンスを渡す方法では駄目でした。

今回は、メソッドに抽出する方向でいこうと思います。
ありがとうございました。



商品マスター a = new 商品マスター();
...
a.レコード.処理メソッド(); // 編集クラスにトランザクション処理メソッドを実装

のようなパターンはいかがでしょうか?

_________________
IEEE-CSDP 2004-2007

[ メッセージ編集済み 編集者: iStation 編集日時 2006-03-06 22:12 ]

スキルアップ/キャリアアップ(JOB@IT)