前の関連記事:linuxBean14.04(167)Travis CIでビルドできるように.travis.ymlを編集
「Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本」のJavaの例をGitHubからダウンロードしてNetBeans8.0.2プロジェクトにする
本のxxxiに載っているサンプルコードへのリンクが切れていましたが、GitHubリポジトリにサンプルコードを見つけました。
bethrobson/Head-First-Design-Patterns: Code for Head First Design Patterns book (2014)
README.mdにはEclipseのプロジェクトに取り込んでコンパイルと書いてありますが、リポジトリにはEclipseプロジェクトは含まれていません。
毎度のことながらプロジェクトの含まれていないGitHubリポジトリのソースをEclipseとかNetBeansのプロジェクトにするのはやりかたがよくわからなくて一苦労します。
JavaはNetbenasで扱うことにしているのでNetaBeans8.0.2のプロジェクトにすることにします。
まずbethrobson/Head-First-Design-Patterns: Code for Head First Design Patterns book (2014)を自分のGitHubアカウントにフォークしてそのURLをコピーしました。
NetBeans8.0.2でチーム→Git→クローン。
宛先ディレクトリにNetBeansProjectsフォルダにしました。
プロジェクトを作成するのか聞かれるので、「プロジェクトを作成」をクリックすると、新規プロジェクトウィザードが起動しました。
Java→既存のソースを使用するJavaプロジェクト。
プロジェクト名をHead-First-Design-Patternsにしました。
プロジェクトフォルダは~/NetBeansProjects/Head-First-Design-Patterns/Head-First-Design-Patternsになってしまうので、~/NetBeansProjects/Head-First-Design-Patternsに変更しました。
「フォルダの追加」、で~/NetBeansProjects/Head-First-Design-Patterns/srcを選択しました。
含めるファイルは「**/*java」としてjavaファイルのみにしました。
これで一つのフォルダにNetBenasプロジェクトとGitリポジトリを収めることができました。
プロジェクトの作成方法はEclipseよりわかりやすいけど、Gitリポジトリの扱いはEclipseの方がわかりやすい、、、
とりあえず自分のGitHubアカウントにプッシュしました。
Head Firstデザインパターンの1章の例を実行する
第1章の例はheadfirst.designpatterns.strategyパッケージにあります。
実行→プロジェクト(Head-First-Design-Patterns)を実行。
メイン・クラスの選択、画面がでてきますので、headfirst.designpatterns.strategy.MiniDuckStimulaterを選択しました。
「1つまたは複数のプロジェクトのコンパイル時にエラーが発生しました。」と言われますが、このパッケージは関係ないのでそのまま「実行」ボタンをクリックしました。
他のメイン・クラスを実行するにはそのjavaファイルをエディタで開いて右クリック→ファイルの実行、で実行できます。
headfirst.designpatterns.strategyにはheadfirst.designpatterns.strategy.MiniDuckStimulater以外にheadfirst.designpatterns.strategy.MiniDuckStimulater1というメインクラスがあります。
どう違うのやら、、、単に実行例のバリエーションのようです。
easyUMLプラグインでJavaソースコードからUML図を作成する
UML(1)NetBeans7のUMLプラグインのリバースエンジニアができないではNetBeansでJavaのソースコードからUML図を作成する方法がわかりませんでしたが今回はうまくいきました。
ツール→プラグイン。
使用可能なプラグインタブで、UMLで検索してでてくる、easyUMLプラグイン(1.2.2)をインストールしてNetBeansを再起動しました。
easyUMLでJavaソースコードからUML図を作成するにはまずUML Diagram Projectを作成しておかないといけません。
ファイル→新規プロジェクト。
UML→UML Diagram Project。
あとはデフォルトのままUMLDiagramsというプロジェクトを作成しました。
headfirst.designpatterns.strategyパッケージを右クリック→easyUML Create Class Diagram、でUML図が出力されました。
最初はいろいろ重なっていて読みにくいので、UML図上で右クリック→Arrange diagram (experimental) で重なりがなくなって、見やすくなります、、、しかし図が大きくなってますます全体像が見づらくなりました。
縮小して全体像を表示する方法はわかりませんでした。
UML図上で右クリック→Export as image→Whole diagram、で全体像をpng形式で出力できました。
しかし2118pxX1991pxもあってすごく見にくいです。
もっと字を大きく、図の間隔をせまくしたいものです。
保存しなければcdgファイルを開き直すと図はアレンジする前に戻りました。
手動で修正したほうがコンパクトにできました。
しかし上の余白はそのまま出力されるので、次回整理するときは上の余白は詰めて整理しようと思います。
矢印の位置は自動的に修正されました。
DisplayDependenciesプラグイン(1.2)というのもあって、これはツールバーが表示されて、ププロジェクトを選択した状態でShow Dependensiesボタンをクリックすると、こんな図が表示されました。
しかし、モジュールの依存関係を表示するものなので、もっと大きなプロジェクト用のもののようなのでアンインストールしました。
StrategyパターンのUML図を読む
UML図についてはLibreOffice(8)統一モデリング言語UML(Unified Modeling Language)の学習でやりました。
easyUMLではこういう注釈が表示されています。
UML図のDuckクラスの周りを抽出して見てみます。
Duckは抽象クラスなのでクラスの名前の上に<<abstract>>が付いています。
属性や操作の名前の先頭にある+はpublic、~は"なし"というアクセス修飾子を示します(- UML超入門_第2章、「Javaの絵本 増補改訂版」P142)。
~(package)と-(private)は小さい字だと見間違ってしまいますね。
+Duck()についているアイコンはインスタンス、~void display()についているアイコンはパッケージ(?)メソッド、他のアイコンはpublicメソッドを示しています。
is付きの矢印はクラスの継承で、implementsはインターフェイスの実装、を示します。
矢頭は、A extends B、ではA→B、A implements B、ではA→B、になっています。
継承では実装をAからBに探しに行くので理解できますが、implementsはBからAに実装を探しに行くので違和感を感じますが、implementsは探しに行く前に決定しているということなのでしょう。
DuckクラスからFlyBehaviorインターフェイスへの矢印は、二つあります。
実線矢印の方はHas(agg)で、破線矢印はUseです。
Has(agg)は集約で、Has(comp)はコンポジションなのでしょうけど、【改訂版】初歩のUML:第4回 少しだけ高度なモデリング技術(その1)関連クラスと集約、コンポジション - ITmedia エンタープライズを読むとこれらの区別は「あいまい」と書いてありますね。
(2017.5.4追記。relationship - Implementation difference between Aggregation and Composition in Java - Stack Overflow、これを読むと、Javaのソースコードからは、A Has B、のBがAの中にカプセル化されていると「コンポジション」、カプセル化されずBが他からも参照されていると「集約」と判断しています。今回の例ではFlyBehaviorもQuackBehaviorもDuckにカプセル化されていないので、UML図では「集約」になっているのです。。。この解釈は違いますね。クラス内でnewで新たにインスタンスを作成していれば、コンポジションになりそうですけど、UML図ではどうして集約になっているのかはわかりません。)
- UML超入門_第2章の図7がわかりやすいです。
「Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本」のP23にはDuck抽象クラスと、FlyBehaviorインターフェイスやQuackBehaviorインターフェイスとの関係はコンポジションと書いてあります。
これはUML図での用語と意味が違うのか、「集約」と「コンポジション」の用語の「あいまい」さの違いか。
Useの矢印は【改訂版】初歩のUML:第5回 少しだけ高度なモデリング技術(その2)クラスの依存関係と実現関係 - ITmedia エンタープライズの「実現関係」かと思いましたが、これは二重カッコが付いていないので、依存関係(dependency)ですね。
UML図全体を俯瞰してみると、「Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本」のP32に書いてある通り「実装に対してではなくインターフェイスに対してプログラミングする」ということがよくわかります。
FlyBehaviorインターフェイスでは3つ、QuackBehaviorインターフェイスでは4つの実装でバリエーションを出しています。
UML図からだけでは、Duck抽象クラスを継承したクラスでどの実装を使っているかはわかりませんね。
でもUML図にするとStrategyパターンの意味がよくわかりました。
参考にしたサイト
bethrobson/Head-First-Design-Patterns: Code for Head First Design Patterns book (2014)
「Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本」の実装例です。
relationship - Implementation difference between Aggregation and Composition in Java - Stack Overflow
「集約」と「コンポジション」のソースコードでの違いの例。
- UML超入門_第2章
クラス図の解説。
【改訂版】初歩のUML:第4回 少しだけ高度なモデリング技術(その1)関連クラスと集約、コンポジション - ITmedia エンタープライズ
UML図の解説。
【改訂版】初歩のUML:第5回 少しだけ高度なモデリング技術(その2)クラスの依存関係と実現関係 - ITmedia エンタープライズ
UML図の解説。
0 件のコメント:
コメントを投稿