こんにちは、キャスレーコンサルティング SI(システム・インテグレーション)部の清水(誠)です。

今回は、シンプルかつメンテナンス性の高いコードを書くために重要な概念のひとつである
「モジュール結合度」について取り上げます。

そういえば情報処理試験を受けた時に覚えはしたけど、実務ではあまり意識する機会がなかったなあ……
という方もいらっしゃるのではないでしょうか。

他ならぬ筆者がそうだったので、今回改めておさらいし、具体例と合わせてご紹介してみようと思います。
今後の実務で活用していただたくきっかけとなれば幸いです。

なお、ここで言うモジュールとは関数や変数を一定の単位でまとめたものを指し、
一般的なオブジェクト指向型言語での「クラス」に置き換えていただいても差し支えありません。
また、サンプルコードはC#にて記述します。

モジュール結合度とは?

モジュール結合度とは、モジュール同士の密接さを表す尺度です。
6段階に分類され、結合度が低いほど独立性が高くなり、良いモジュールとされています。
以下、結合度の高い順にご説明します。

1.内容結合

あるモジュールが、別のモジュールの外部宣言していない内部状態を直接参照したり、
命令の一部を共有したりしている状態を指します。
内容結合では、一方のモジュールの変更が他方のモジュールに影響を及ぼすので
障害につながる確率が高くなります。

アセンブラ等の低水準言語では陥りがちですが、高水準言語では一般的には発生しないためサンプルコードは省略します。

2.共通結合

共通域に定義したデータをいくつかのモジュールが直接使用するような状態を指します。
共通域の定義データとはいわゆるグローバル変数、JavaやC#で言うところのstatic変数です。

・共通域のデータは他のモジュールで書き換えられてしまう可能性がある
・共通域のデータ定義の変更がそれを使用しているモジュール全てに影響する

等、デメリットが多くあります。

サンプルコード

using System;

public class CommonParameter
{
    // 共通域のデータ
    public static string Name;
    public static int Number;
    public static string Place;
}

public class CommonCoupling {
    public string GetMessage(){
        var message = CommonParameter.Name + "が" + CommonParameter.Number + "匹います。";
        return message;
        // CommonParameter.Placeは使用しない
    }
}

public class TestCommon
{
    public static void Main() {
        CommonParameter.Name = "犬";
        CommonParameter.Number = 2;
        CommonParameter.Place = "庭";
        var data = new CommonCoupling();
        Console.WriteLine(data.GetMessage());
    }
}

実行結果
 犬が2匹います。

3.外部結合

外部宣言したデータ(= public static変数)を共有している状態を指します。
データを共有するという点では共通結合と似ていますが、必要なデータのみを外部宣言するため
共通結合よりも結合度は弱くなります。

サンプルコード

using System;

public class ExternalCoupling {

    // 必要なパラメータをstatic化
    public static string Name;
    public static int Number;

    public string GetMessage(){
        var message = Name + "が" + Number + "匹います。";
        return message;
    }
}

public class TestExternal
{
    public static void Main() {
        ExternalCoupling.Name = "猫";
        ExternalCoupling.Number = 3;
        var ext = new ExternalCoupling();
        Console.WriteLine(ext.GetMessage());
    }
}

実行結果
 猫が3匹います。

4.制御結合

呼び出し側のモジュールが、呼び出されるモジュールの制御を指示するデータ(いわゆるフラグ)を
パラメータとして渡す状態を指します。呼び出し側は相手のモジュールのロジックを知っている必要があるため、
相手をブラックボックス扱いできず結合度が強くなります。

サンプルコード

using System;

public class ControlCoupling {
    public string GetMessage(string name, int number, string type){
        string message = string.Empty;

        // 引数typeによって処理を分岐
        if (type == "哺乳類")
        {
            message = name + "が" + number + "匹います。";
        }
        else if (type == "鳥類"){
            message = name + "が" + number + "羽います。";
        }
        return message;
    }
}

public class TestControl
{
    public static void Main() {
        var ctrl = new ControlCoupling();
        Console.WriteLine(ctrl.GetMessage("ハムスター", 4, "哺乳類"));
        Console.WriteLine(ctrl.GetMessage("ハト", 5, "鳥類"));
    }
}

実行結果
 ハムスターが4匹います。
 ハトが5羽います。

5.スタンプ結合

共通域にないデータ構造を、2つのモジュール間で受け渡す状態を指します。
結合度は比較的弱いですが、スタンプ結合の場合は受け渡すデータ構造の一部を使用しないことがあります。

サンプルコード

using System;

public class StampCoupling {
    public string GetMessage(StampParameter p){
        var message = p.Name + "が" + p.Number + "匹います。";
        return message;
        // p.Placeは使用しない
    }
}
public class StampParameter
{
    // 受け渡し用データ(インスタンス変数なので共通域ではない)
    public string Name;
    public int Number;
    public string Place;

}

public class TestStamp
{
    public static void Main() {
        var p = new StampParameter() ;
        p.Name = "アリ";
        p.Number = 6;
        p.Place = "地中";
        var stmp = new StampCoupling();
        Console.WriteLine(stmp.GetMessage(p));
    }
}

実行結果
 アリが6匹います。

6.データ結合

単純なデータだけをパラメータとして受け渡す状態を指します。
相手モジュールをブラックボックス化できるので、結合度は一番弱くなります。

サンプルコード

using System;

public class DataCoupling {
    public string GetMessage(string name, int number){
        var message = name + "が" + number + "匹います。";
        return message;
    }
}

public class TestData
{
    public static void Main() {
        var data = new DataCoupling();
        Console.WriteLine(data.GetMessage("コツメカワウソ", 7));
    }
}

実行結果
 コツメカワウソが7匹います。

おわりに

一般的に、モジュール同士の結合度が低いほどコードの可読性・再利用性が高まり、
障害が発生した場合も対応がしやすくなります。

プロダクト毎のアーキテクチャやコーディング規約の許す範囲で、
可能な限り結合度を弱く保つコーディングを心掛けましょう。

最後までお読みいただきありがとうございました。


こんにちは、キャスレーコンサルティングのSI(システム・インテグレーション)部の中尾です。

初めに

MicrosoftがC# 6よりC#のコンパイラをC#で作成しました。このC#コンパイラを“Roslyn”と呼びます。

以降Visual StudioはコンパイラとしてこのRoslynを使用する様になりましたが、合わせてRoslynのコンパイラの機能を利用するAPIをライブラリとして公開してくれたため、開発者はC#プログラム側からC#ソースをコンパイルしたり構造解析を行ったりするなどのソースコードの構文に関する処理が出来るようになりました。

前回の記事「Roslyn for Scripting – C#プログラム内でC#で書かれたスクリプトを実行しよう」ではその中のRoslyn for ScriptingというC#をスクリプト実行できる機能を紹介いたしました。

今回は、RoslynのAPIを使って、C#のソースコードの構造解析の方法を紹介したいと思います。 (続きを読む…)


こんにちは、キャスレーコンサルティングのSI(システム・インテグレーション)部:藤沢です。

前回のブログ「Xamarinでマルチデバイス開発(インストール編)」ではXamarinのインストール を行いましたので、
今回はAndroidの実機でデバッグを行いたいと思います。 (続きを読む…)


こんにちは、キャスレーコンサルティングのSI(システム・インテグレーション)部:藤沢です。

今回は、XamarinをインストールしてAndroidアプリを作成したいと思います。
XamarinはネイティブのiOS、Android、Windowsのアプリを一般的なC#/.NETコードベースから構築するための
モバイルアプリ開発プラットフォームです。(MSDNより) (続きを読む…)


こんにちは、キャスレーコンサルティングのSI(システム・インテグレーション)部の中尾です。

今回紹介するスクリプトは、「Roslyn for Scripting」と言って
「C#のプログラム内でC#で書かれたスクリプトを実行できる」物です。
(続きを読む…)


UI Automationを使用したUIテスト

Posted on 03月 31, 2016

こんにちは、キャスレーコンサルティングのSI(システム・インテグレーション)部:藤沢です。
今回は、UI Automationを使用してC#のアプリケーションのUI部分のテストの自動化を行います。 (続きを読む…)


こんにちは、SI部の藤沢です。
前回(LinuxでもC#プログラミング(導入編)) にMonoのインストールを行ったので、簡単なGUIアプリケーションの作成をします。
今回のアプリケーションは、社員簿(ID、名前、メールアドレス)で下記を要件とします。

  • データの一覧表示が行える。
  • 名前で検索が行える。
  • 新規登録・編集登録(保存先はXMLファイル)が行える。

(続きを読む…)


こんにちは、SD部の江本です。
今回は、C#によるスクレイピング処理について記述したいと思います。

構成

  • はじめに
  • 何か活用できるの?
  • 注意事項
  • 環境
  • 実際に取得してみよう!
  • 終わりに

はじめに

ネット社会になって随分経ちますが、ネット上には無数の情報が眠っています。
スマホ、タブレット、PCと色々な方法でネットにアクセスできる端末が増えてきていますね。

それらの端末が各サイトへアクセスし、どのように情報を取得しているのか?
また、それらの情報を取得して、データの分析や解析等を実施してみたいなと思った人はいらっしゃいませんか?

その中でも今回は、ウェブスクレイピングという技術です。
簡単に説明しますと。。。

ウェブスクレイピングとは

Webスクレイピングとは、WebサイトからWebページのHTMLデータを収集して、

特定のデータを抽出、整形し直すことである。

ウェブスクレイピング – Wikipedia

WEBサーバと通信してHTMLを取得してみるという試みです。
この技術を知った当時、少し調べてみたらPHPでのスクレイピング処理が数多く検索にHITしました。
今回は、そのスクレイピング処理をC#で書いてみたい!と思い企画してみました。

本稿は、DB周りなどの処理も書かないで、基本的なところであるURLからHTML取得。

取得したHTMLから特定の情報を取得する、というところをゴールとして記載しようと思います。 (続きを読む…)


こんにちは、SI部の藤沢です。
今回は、LinuxでC#プログラミングを行うためのMonoの導入を行います。

構成

  • Ubuntu 14.04 LTS(仮想イメージ)
  • Mono
  • MonoDevelop

今回は、Ubuntuを使用してC#の実行環境を構築していきます。

Ubuntuのインストール

Ubuntuのサイトに仮想マシン用のファイルがあるため、これを使用します。
VirtualBoxをインストールし、ダウンロードした仮想イメージ(Ubuntu 14.04 LTS)を展開し仮想マシンの登録を行います。
Ubuntuのサイト通りに設定します。
VirtualBoxを起動し、[新規]をクリックします。仮想マシン作成ウィザードが開くので、画面の指示に従って入力していきます。
OSタイプは「Ubuntu」を選択します。 (続きを読む…)



  • Profile
    キャスレーコンサルティングの技術ブログです。
    当社エンジニアが技術面でのTips、技術系イベント等についてご紹介いたします。
  • CSV社長ブログ
  • チーム・キャスレーブログ