【コードで分かるUMLシリーズ】属性とプロパティ


.NETのプロパティ

.NETで開発している人は、プロパティって知っていますよね。
これです↓。

Sample1.cs
class Sample {
    // フィールド
    private string property1;
    // プロパティ
    public string Property1
    {
        set{
           this.property1 = value;
        }
        get{
           return this.property1;
        }
    }
}

これは、

Sample4.cs
class Sample {
    // プロパティ
    public string Attribute1 { set; get; }
}

なんて書くこともできます。

マイクロソフトの
『プログラミング .NET Framework 第4版』
第10章 プロパティ P254に、

型のフィールドを外部に公開すると、オブジェクトのステートを破壊してしまうような方法でフィールドを不正に使用するコードを記述してしまう危険性が高くなる

型のデータフィールドへのアクセスをカプセル化する

プロパティ(property)と呼ばれる仕組みを提供しています。

と書いてあります。

つまり、プロパティは、データフィールドへのアクセスをカプセル化するための仕組みです。

上のSample3.csコードにコメントしましたが、privateの部分はフィールドです。
publicの部分がプロパティです。

Sample4.cs の例なんて、そもそも、主役であるはずのフィールドを実装せずに、
サポート役のプロパティだけを実装しています。
なんか、違和感ありませんか?

UMLのプロパティ

UMLでプロパティというと、クラスの属性を表している型の名前です。
属性=attribute
属性の型は、propertyです。

この図の関係です。
「クラスは、プロパティ型の属性を持っている」です。

.NETのプロパティとUMLのプロパティの違い

つまり、.NETのプロパティは、.NET上用意されたデータフィールドをカプセル化する仕組みであり、
UMLのプロパティは、属性の型ということで、全く違うものだと分かります。

UMLの属性をコードで表現すると

では、改めて、UMLの属性をコードで表現してみましょう。

C#のカプセル化する仕組みを使わない場合

Sample2.cs
class Sample {
    // フィールド
    public string attribute1;
}

C#のカプセル化する仕組みを使う場合

Sample3.cs
class Sample {
    // フィールド
    private string attribute1;
    // プロパティ
    public string Attribute1
    {
        set{
           this.attribute1 = value;
        }
        get{
           return this.attribute1;
        }
    }
}

上のサンプルコード(Sample1.cs)では、
フィールドに、「プロパティの名前の先頭を小文字にした名前」を付けていました。
また、上のサンプルコード(Sample4.cs)では、
フィールド自体が登場しません。

本来は、プロパティは属性をカプセル化する仕組みなだけですから、
フィールドが主役である方が自然です。

プロパティは、メソッドの一種であって、フィールドの一種ではありませんから、
属性がメソッド主体で実装されるのには、違和感が伴います。

些細なことかも知れませんが、UMLモデリングと実装コードの関係を考えるときは、
こういった元々の考え方を大切にしたいです。

まとめ

C#のプロパティって、
UMLの属性のことだと思っていたり、
C#で属性の実装方法だと思っていたる人がよくいますが、
どちらでもありません。

UMLの属性は、C#コードでは、
・フィールドか、
・フィールド+カプセル化する仕組み
で表現できます。