foo() {
double dSeta, dTan;
...... /* dSetaを設定する */
dTan = tan(dSeta); /* タンジェントを求める*/
}
このように単純な変数による結合です。
typedef struct {
long lEmployeeID;
char szName[40];
char szAddress[100];
long lBirthDay;
char szPhone[20];
} EMPLOYEETYPE;
foo() {
EMPLOYEETYPE Emp;
/* Empに設定 */
...
PrintEmployeeData(Emp); /* EmployeeData全体を印刷 */
}
このようにデータ構造を渡す結合です。ところで…
foo2() {
EMPLOYEETYPE Emp;
/* Empに設定 */
...
PrintEmployeeName(Emp); /* EMPLOYEETYPEのszNameを印字 */
}
こんな場合はどうでしょうか。これもデータ構造による結合をしています。
foo2_dash() {
EMPLOYEETYPE Emp;
/* Empに設定 */
...
PrintEmployeeName(Emp.szName);
}
こんなふうに、単純なデータによる結合に昇華(あえて昇華としたい)させましょう。では、lEmployeeID以外の情報を使うルーチンがあったらどうしましょう?
単純データ結合でパラメータをたくさん並べる。
あるいは、データ構造による結合で、Emp全体を渡し、渡されたほうではlEmployeeID以外を使うようにする。
どちらも間違いではありません。
でも…
typedef struct {
long lEmployeeID;
struct tagEMPDATA {
char szName[40];
char szAddress[100];
long lBirthDay;
char szPhone[20];
} data;
} EMPLOYEETYPE;
foo3() {
EMPLOYEETYPE Emp;
/* Empに設定 */
...
PrintEmployeeData(Emp.data);
}
こんなふうに、データからなるサブストラクチャを作成するのがもっともスマートな解決法ですね。
foo() {
DoProcess(1);
DoProcess(2);
}
DoProcess(int flag) {
if (flag == 1) {
/* 月次報告書印刷処理 */
...
}
if (flag == 2) {
/* 四半期報告書印刷処理 */
...
}
if (flag == 3) {
/* エラー表示処理 */
...
}
if (flag == 4) {
/* メール送受信処理 */
...
}
}
この結合は望ましくありません
まず名前がよくありません。DoProcess()?なにをするのでしょう?
フラグによる結合を行うと、このようによく解らないネーミングが増えます。
また、「何をする関数」かどうかの定義があいまいになり、グローバル変数を使用する機会が増えます。
ルーチン内で処理対象を切り替えるような作りは、望ましくありません。
typedef struct {
long lEmployeeID;
char szName[40];
char szAddress[100];
long lBirthDay;
char szPhone[20];
} EMPLOYEETYPE;
EMPLOYEETYPE EmpTbl[100];
foo () {
EmpTbl[0].lEmployeeID = 1;
/* EmployeeID(従業員コード)を設定する…つづく */
...
/* EmployeeID(従業員コード)を設定する…ここまで */
EmpTbl[99].lEmployeeID = 100;
PrintEmployeeID(50)
}
PrintEmployeeId(int nTableIndex) {
/* EmpTbl[nTableIndex].lEmployeeID を印刷する...*/
...
}
この結合は望ましくありません このような結合はプログラムの可読性、保守性を著しく害します。
| ルーチンへ戻る | _ | Top of Site |