OCLとは何か?

OCLとは何か?

Object Constraint Languageの略。オブジェクト制約言語。

特徴

  • ソフトウェアのモデルを記述するためのモデリング言語の1つである。
  • UMLの追加機能(add-on)である。
  • OCLの式(expression)は、UMLで定義された型を使用している。
  • OCLで記述された式は、UMLなどでモデリングされた成果物に、不可欠な情報を追加することができる。
  • OCLで追加する情報は、UMLの図だけでは表現することが不可能だったり、難しいものを含んでいる。
  • UML1.xでは、OCLによって追加される情報は、制約(constraint)に限定されるべきだとされていたが、UML2.0は、次に示すものも、OCL式で記述するべきだとされている。
    • 問い合わせ(クエリー)
    • 値の参照
    • 条件の指定
    • モデル中のビジネスルールの指定
  • 制約言語でもあり、問い合わせ言語でもある。
  • OCLは、誰でも独自の構文を定義することができる。その条件は、言語構造へマップできるということ、ただ1つである。
  • OCLは、Java, C#, Eiffelなどと同様に型付けされた言語である。したがって、型、構文レベルのチェックが可能であり、これにより、モデル中のエラーを検出し、取り除くことが容易である。
  • OCLは、そのさまざまな特徴により、実装に依存することなく、モデルの意味するところを正確に記述することができる。これにより、UML/OCLモデルを『完全なPIM(プラットフォーム独立モデル)』にすることができる。
  • OCLのすべての式のスーパークラスは、OclExpressionメタクラスである。
  • 言語のメタモデル == 抽象構文(Abstruct Syntax)。言語はメタモデルによって定義される。

OCLとUMLで何ができるのか?

  • 正しい(Good)なモデル
  • 内容の充実(Solid)したモデル
  • 矛盾のない(Consistent)モデル
  • 首尾一貫(Coherent)したモデル

上のようなモデルを作り上げることができるため、MDAの本質である『モデルをソフトウェア開発の基礎とする』ということを、実現する方法として非常に有効である。

OCLはどんな目的で使用されるか?

  1. クエリー言語(問い合わせ)
  2. 不変式(invariant)
  3. 事前条件(pre condition)
  4. 事後条件(post condition)
  5. メッセージやアクションのターゲットを指定するため。
  6. 操作(operation)の制約を指定するため。
  7. 派生ルール(deriviation rule)を指定するため。

OCLを使うことのできる場所は?

OCLは、モデルの中のあらゆる場所で、値を示すために使用することができる。

値とは?

integerのような単純な値、オブジェクトや値の集まり、または、オブジェクトへの参照の集まりなど、さまざまなものが値となる可能性がある。

宣言型言語

OCLは、宣言型言語である。
つまり、「どのように」ではなく、「何が」なされるべきかということを表す。
これを確実なものにするため、OCLで記述されたいかなる式も、副作用を持つことは一切なく、システムの状態が、OCL式によって変わることはない。

キーワードと例

不変式(invariant)
  context ContextName inv :
  self.attribute > 100
事前条件(pre)と事後条件(post)
  context ContextName::operation():ReturnType
  pre : param01 > 100
  post : result = 100
初期値(init)
  context ContextName::Attribute
  init : 初期値
派生ルール(derive)

(属性などの場合)

  context ContextName::Attribute
  derive : SuperClass.Feature.Attribute

(問い合わせ操作の場合)
これは、システムの状態を変えず、値や値の集合を返すだけのクエリー操作である。
コンテクストで、操作名、パラメータ、戻り値の型(シグニチャ)を記述する。
いっぽう、ボディには、この問い合わせ操作が何を行うかを記述することができる。

  context ContextName::operation():ReturnType
  body : なにかしらの操作など()
         if さらに何かの操作
         then 真の場合に実行される式
         else 偽の場合に実行される式
         endif
新たな属性や操作の定義(def)

定義する属性とその型を、defに続けて記述する。

  context ContextName
  def : newAttribute : Integer = DeriveRule.member->getVal()

操作を定義する場合、その操作は常に問い合わせ操作である。

  context ContextName
  def : getAttributeName():String = DeriveRule.getAttributeName()
変数の宣言(letキーワード)

let式は、あらゆる種類のOCL式に含まれる可能性がある。新しく定義された変数は、この特定の式の中だけで有効である。

変数は、キーワード、letに続けて変数名 : 変数の型 = 派生ルール、というように記述する。

  context ContextName
  inv : let newAttribute : Boolean 
                         = self.feature.attribute01 and self.feature.attribute02

        in
            if valid  then
                newAttribute = false
            else
                newAttribute = true
            endif

OCL式のコンテクスト

  • コンテクスト定義は、OCL式のあるモデル実体を指定するものである。
  • 通常、クラス、インターフェース、データ型、コンポーネントである。しかし、操作、インスタンスであることもありうる。
  • コンテクストは、UMLの図で定義された特定の要素である。この要素のことをコンテクストと呼ぶ。

selfキーワード

コンテクストインスタンスを明示的に参照する必要のある場合に使う。

  context ContextName
  inv : self.name = "EffectiveGOF23"

不変条件の継承

  • スーパークラスで定義されている不変条件は、サブクラスに継承される。
  • サブクラスは、その不変条件を強めることは許されるが、スーパークラスでの定義を弱めることはできない。
  • あるクラスのインスタンスが、期待されているすべての場所において、常にそのクラスのサブクラスのインスタンスを使うことができる。所謂、『リスコフ(Liskov)の置換原則』である。
  • あるクラスで定義されている操作を、サブクラスが継承し、再定義する場合、サブクラスは、その操作の事前条件(pre condition)を弱くすることは許されるが、強くすることはできない。
  • あるクラスで定義されている操作を、サブクラスが継承し、再定義する場合、サブクラスは、その操作の事後条件(post condition)を強くすることは許されるが、弱くすることはできない。

OCLの基本要素

これらは、UMLモデル要素を参照することなく利用することができる。
大きく分けると次の2種類。

  1. OCLの標準ライブラリで定義されている型
    1. 基本型(Integer、Real、String、Boolean)
    2. コレクション型(Collection、Bag、OrderedSet、Set、Sequence)
  2. ユーザ定義型(UMLモデルにおいて、ユーザに定義される型)

OCLのコメント

ハイフンを2つ書くと、それに続く同一行の内容はコメントとして扱われる。

  context ContextName
  --このコンテクストでの不変条件を以下に示す。
  inv : Attribute01 > 100

もしくは、スラッシュ+*、と、*+スラッシュで囲んだ範囲がコメントとして扱われる。

  context ContextName
  /*
     このコンテクストでの不変条件を以下に示す。
     Attributeは常に100よりも大きくなければならない。
  */
  inv : Attribute01 > 100

Boolean型と、その演算

演算 記法 戻り値の型
or a or b Boolean
and a and b Boolean
exclusive or a xor b Boolean
negation not a Boolean
equals a = b Boolean
not equals a <> b Boolean
implies a implies b Boolean

Boolean型の標準演算『implies演算』について

  implies   a implies b

  ※ a, bともにBoolean型


  aがTrueのとき、bもTrueなら、式の結果もTrueとなる。

  aがFalseであるとき、式の結果は、bの値にかかわらず、常にTrueと評価される。

Boolean型の if-then-else 演算

  if  then
      
  else
      
  endif


  これは、以下と同じ。

  if (expression){
      true case cord ;
  } else {
      false case cord ;
  }

Integer型とReal型の演算

演算 記法 戻り値の型
equals a = b Boolean
not equals a <> b Boolean
less a < b Boolean
more a > b Boolean
less or equals a <= b Boolean
more of equals a >= b Boolean
plus a + b Integer or Real
minus a - b Integer or Real
multiplication a * b Integer or Real
division a / b Real
modulus a.mod(b) Integer
integer division a.div(b) Integer
absolute value a.abs(b) Integer or Real
maximum a.max(b) Integer or Real
minimum a.min(b) Integer or Real
round(四捨五入) a.round() Integer
floor(切り捨て) a.floor() Integer

String型と演算

演算 記法 戻り値の型
concatenation string.concat(string) String
size string.size() Integer
to lower case string.toLower() String
to upper case string.toUpper() String
substring string.substring(int, int) String
equals string01 = string02 Boolean
not equals string01 <> string02 Boolean

UMLメタモデルの設計原則

UMLメタモデルの設計原則

UMLメタモデルの原則として以下の5項目が挙げられる。

  • モジュール化(Modularity)
  • 階層化(Layering)
  • 区画化(Partitioning)
  • 拡張性(Extensibility)
  • 再利用性(Peuse)
モジュール化(Modularity)
強疑集と疎結合の2つの原則により、構成要素をパッケージにグループ化し、特性をメタクラスに組織化する。
階層化(Layering)
2つの方法でUMLメタモデルに適用されている。
  1. パッケージは、メタ言語のコア構成要素を、それを使用する、より高いレベルの構成要素から分離するために階層化されている。
  2. 抽象化、特にインスタンス化を分離するために、4階層メタモデルアーキテクチャパターンが適用されている。
区画化(Partitioning)
同じ階層内において、概念による組織化をするために使用されている。インフラストラクチャライブラリの場合、現在、将来のメタモデリング標準に対応するため、きめ細かく区画されている。いっぽう、UMLの場合、パッケージ内の結合を強め、パッケージ缶の結合を緩めるため、区画化は荒削りである。
拡張性(Extensibility)
UMLは、2通りの方法で拡張することができる。
  1. プロファイルで方言を定義し、特定のプラットフォームやドメインに対応するようにUMLを拡張することができる。
  2. インフラストラクチャライブラリを再利用し、UML言語ファミリーの新たなメンバとなる言語を規定することができる。
再利用性(Peuse)
MOF(メタモデル・オブジェクト・ファシリティ)やCWM(コモン・ウェアハウス・メタモデル)のような、他のアーキテクチャ的に関係するメタモデルだけではなく、UMLメタモデルを定義するために再利用される、柔軟なメタモデルライブラリが提供される。

Core(コア)

Core(コア)

完全なメタモデル
コア・パッケージは、再利用性が高い設計のされた、完全なメタモデルである。
コアを特化/インポートするもの
UML、MOF、CWM、Profilesなどは、コアを特化、もしくは、インポートしている。
MDAの核心
共通コアは、MDA(モデル駆動アーキテクチャ)の核心である。
再利用性
コア・パッケージは、PrimitiveTypes、Abstractions、Basic、Constructsに再分割されている。このことによって、再利用することが、より容易になっている。

PABCの順番で覚えてみれば。ピーエービーシー

Package名 依存しているPackage数 このPackageに依存しているPackage数
PrimitiveTypes 0 2
Abstractions 1 2
Basic 2 1
Constructs 2 0

4層アーキテクチャ

4層アーキテクチャ


図に示すように、4つのメタレベル(レイヤー)がある。

M3(メタメタモデルレイヤー)
最上位のレイヤー。UML、CWMなどのメタモデルを定義するために使われている。
M2(メタモデルレイヤー)
このレイヤーには、M3のインスタンスである、UML、CWMなどが含まれる。
M1(モデルレイヤー)
このレイヤーには、M2のインスタンスである、UMLなどによって定義されるモデル要素が含まれる。
M0(インスタンスレイヤー)
このレイヤーには、M1のインスタンスである、実行時のインスタンスが含まれる。

インフラストラクチャライブラリーパッケージ

インフラストラクチャライブラリーパッケージ


このパッケージに含まれるものは、図に示されているように、次の2つのパッケージである。

  • Core
  • Profiles
Core(コア)
コアは、メタモデルの定義に使われる。
Profiles(プロファイル)
プロファイルは、メタモデルの拡張に使われる。

MDA(Model Driven Architecture)

MDA(Model Driven Architecture)

MDAに関連のあるOMGの標準規格には以下のようなものがある。

  • UML(Unified Modeling Language)
  • XMI(XML Metadata Interchange)
  • CORBA(Common Object Request Broker Architecture)