Comments
Description
Transcript
Lecture5
7. モジュール化設計 内容: モジュールの定義 モジュールの強度 又は結合力 モジュール連結 モジュールの間の交信 7.1 モジュールの定義 プログラムモジュールとは、次の特徴を持つプログラムの 単位である。 モジュールは、一定の機能を提供する。例えば、入力に よって、ある出力を出す。 モジュールは、同じ機能仕様を実装しているほかのモ ジュールに置き換えられる。この変化によって、プログラ ム全体に影響をあまり与えない。 モジュール化設計の基本アイデアは、他の製品の生産 プロセスと同じように考える。 具体的には、モジュールは、次のプログラム単位に 解釈できる: A procedure in Pascal. 操作レベルの A function in C. モジュール An operation in general. A process in DFDs. A method in Java. 高いレベル A unit that groups operations. のモジュール A class (e.g., a Java class). 事例 (1) 操作レベルのモジュール: Java メソッド: class ExampleModule { int x, y; int Swap() { int a = 0; //local variable declaration a = x; x = y; y = a; } } //statement-1 //statement-2 //statement-3 (2) 高いレベルのモジュール: module A; variable declarations; operation-1; operation-2; operation-3; … operation-n end-module 幾つかの操作を グループする 高いレベルのモジュール: Java クラス。 class Calculator { int reg; public Calculator() { initialize reg; } //constructor of the class public int Add(int i) { reg = reg + i; } public int Subtract(int i) { reg = reg – i; } public int Multiply(int i) { reg = reg * i; } } 7.2 モジュールの強度又は結合度 下の議論には、操作レベルのモジュールを使う。 定義: モジュールの強度(strength)又は結合度 ( cohesion)は、文又は操作が同じモジュールに 所属する程度を測る尺度である。 一般原則 同じタスクを完成するために必要な文又は操作が 同じモジュールに所属する訳である。 モジュール設計の指針 一つのタスクを完成するためにモジュールを作成する。 例えば、計算機Calculatorクラスの中で、定義されてい る操作Add, Subtract, およびMultiplyそれぞれ操作は、 モジュールとして見られる。 関係が薄い幾つかのタスクがひとつのモジュールに置 くことができる。ただし、これらのタスクが、プログラム の中で同じ時間で実行されるため、同じモジュールに 置く。例えば、幾つかの変数らを初期化する文を同じ モジュールに置く。 ひとつ以上の関係があるタスクを実装する文を同じモ ジュールに置くこともできる。 例えば、 プログラムの実 行の最後に、データをファイルに書き込む文を同じモ ジュールに置く。 7.3 モジュール連結(coupling) 定義: モジュール連結は、プログラムモジュール間の独立 性の程度を測る基準である。 一般的に、モジュール連結は、強くなればなる ほど、一つのモジュールがほかのモジュールへの 影響を与える可能性が高くなる。例えば、大家族 と小家族と比べて、大家族の成員の間の影響は 小家族より相互影響力が高い。 一般的には、引数を通じてモジュール連結する場合は グローバル変数を通じてモジュール連結する場合より、 モジュール連結を弱める。 事例 class Calculator { int reg; void Calculator() { initialize reg; } //constructor of the class int Add(int i) { reg = reg + i; Use the } same int Subtract(int i) { global variable reg = reg – i; reg. } int Multiply(int i) { reg = reg * i; } } Use no common global variable class Calculator { void Calculator() { } //constructor of the class int Add(int reg, int i) { return reg + i; } int Subtract(int reg, int i) { return reg – i; } int Multiply(int reg, int i) { return reg * i; } } 7.4 モジュールの間の交信 プログラムは、一般的に幾つかのモジュールから構成 される。プログラムの機能を提供するため、モジュールの 間に交信することが必要である。 モジュールの間の関係を、モジュールの呼び出しに よって作られる。 一つのモジュールから、もう一つのモジュールを呼び出す ときに、必要なデータ項目を提供することが必要である。 それらのデータ項目が、引数またはグローバル変数に よってできる。 交信手段 引数によって交信する。 グローバル変数によって交信する。 次の二つのプログラムを通じて、モジュール連結の 概念を説明する。 問題: プログラムは、10個の0ではない違う整数を 入力して、二つの数字を出力する。 (1) 10個の整 数の平均値より大きい整数の数。 (2) 10個の整 数の平均値より小さい整数の数。 例えば、 入力: 5, 78, 56, 89, 12, 24, 75, 98, 34, 68 (average = 539 / 10 = 53.9); 出力: count1 = 6 (大きい整数: 78, 56, 89, 75, 98, 68) count2 = 4 (小さい整数: 5, 12, 24, 34) 二つのJava-擬似コード プログラム 1: import java.io.*; public class CountNumbers { //there is no “global” variables here public static void main(String args[]) { int numbers[] = new int[10]; int count1 = 0, count2 = 0; double average = 0.0; for (int i = 0; i < numbers.length; i++) INPUT numbers[i]; average = CalculateAverage(numbers); count1 = CountGreater(average, numbers); count2 = CountSmaller(average, numbers); OUTPUT count1 and count2; } double CalculateAverage(int a[]) //obtain average { int total = 0; double ave = 0.0; for (int j = 0; j < a.length; j++) total = total + a[j]; ave = total / 10; return ave; } int CountGreater(double ave, int a[]) { int count1 = 0; for (int k = 0; k < a.length; k++) if (a[k] > ave) count1 = count1 + 1; return count1; } int CountSmaller(double ave, int a[]) { int count2 = 0; for (int k = 0; k < a.length; k++) if (a[k] < ave) count2 = count2 + 1; return count2; } } プログラム 2: import java.io.*; public class CountNumbers { //there are four “global” variables here static int numbers[] = new int[10]; static double average = 0.0; static int count1 = 0, count2 = 0; public static void main(String args[]) { for (int i = 0; i < numbers.length; i++) INPUT numbers[i]; CalculateAverage(); CountGreaterSmaller(); //compute count1 and count2 System.out.println("Count1:" + count1); System.out.println("Count2:" + count2); } static void CalculateAverage() { // Obtain average int total = 0; for (int j = 0; j < numbers.length; j++) total = total + numbers[j]; average = total / 10; } static void CountGreaterSmaller() { for (int k = 0; k < numbers.length; k++) if (numbers[k] > average) count1 = count1 + 1; else count2 = count2 + 1; } } 利点と弱点 グローバル変数を通じで交信の場合は、モジュール連 結を強め、モジュールの独立性を弱める。このような交 信方法は、モジュール化設計の立場から見ると、よくな い方法である。 グローバル変数を通じてモジュールの間の通信の場合 は、プログラムの実行する効率が高くなる。 引数によって交信する場合は、モジュールの独 立性を強める。しかし、プログラムの効率が減ら す可能性が高い。