開発環境

phpdocの勘所

2016-06-17 19:07 - NozawaTakeshi

ご無沙汰しております。インターエデュ・ドットコム、開発担当の野澤です。
なかなか記事を更新できず申し訳ありません。

実は弊社は昨年ウェブサーバのリプレースを行いまして、大幅にサーバ環境が刷新されたのですが、今年はプログラム環境の刷新を行っていきたいと個人的に思っております。

弊社は10年以上ウェブサービスの開発を行っておりますが、その間様々なエンジニアがプログラム開発に関わっております。そのため、人によって書き方も違い、プログラムも大分レガシーになってきています。いろんなところに、同じようなプログラムが書かれていたりします。

なるべく仕様や開発の背景、バグの要因や解決方法はredmineのチケットにまとめて書いてはいるものの、集約されず散在しており見通しがあまりよくありません。

そこで今後の開発効率をあげていくためにも、弊社では”phpDocumentor“を使ってきちんとドキュメントを作成してくことにしました(以下phpdoc)。

今回はphpdocのインストール方法やドキュメントのテンプレートの指定方法、ドキュメントの書き方について見ていき、
最後にドキュメントを作成することのメリットについて考えてみたいと思います。

インストール方法

PEARでもPHARでもComposerでもインストールできます。
基本的にはPHARでインストールするのが一番簡単だと思いますが、
Phing(後日触れます)で実行する場合はPEARでインストールしなければなりませんのでご注意ください。

phingでphpdocを実行する際の要件

PEARでのインストール方法

テンプレートについて

ドキュメントの書き方の前に、テンプレートについてご紹介します。
ドキュメントは生成時にいくつかのテンプレートを選ぶことができます。
phpdocの2.8.5では下記の9つのテンプレートから選ぶことができます。

デフォルトでは”clean”が採用されます。

ただし問題点として、cleanテンプレートは基本的にnamespaceの利用を前提としています。
機会があればnamespaceについての説明をしたいと思いますが、namespaceを使っていないと、クラスがずらーっと並んで階層化されず、非常に見難いです。

環境によってはnamespaceを採用できない、採用しない場合も多数あると思います。
その場合は”responsive”テンプレートがおすすめです。

こちらであればnamespaceを使っていなくても@packageで指定した階層通りに
分類・表示してくれます。

テンプレートを指定してドキュメントを作成する場合は下記のように–templateオプションを指定します。

書き方

基本的な書き方については既に様々なブログや公式ドキュメントで紹介されているので割愛しますが、ここでは特に私が気をつけている@package, @throws, @todoの3つのタグの使い方について掘り下げてみたいと思います。

 タグ

@package

主にクラスにつけることの多いタグです。
そのクラスがどのパッケージに属するのかを記します。

たとえば

というようにタグ付けすれば、「Hogeパッケージのなかにある、fooサブパッケージのSomeClass」というようにphpdocは解釈してくれます。
そうすることで、パッケージ全体を樹形図のように見て取ることができます。

先ほども触れたとおりデフォルトのcleanテンプレートではnamespaceを使っていない限り階層表示してくれません。ただし、responsiveなどのテンプレートでは@packageを使えば階層表示してくれます。

なお、namespaceを使っていてディレクトリ構造とネームスペースの構造が等しい場合は、@packageは使わないほうが良いと公式ドキュメントには書いてあります。

ちなみに公式ドキュメントによると@packageは論理構造でnamespaceは機能的な構造を示すと書いてありました。

PSRに準拠していれば上記のとおりになるはずなので、その場合は@packageは省略できますね(PSRについても後日書きたいと思います)。

@throws

普段、例外を使うことはあまりなかったのですがドキュメントを作成するようになってからは異常系の処理に対しては例外をきちんと使うようになりました。

@throwsタグを使えば、いつ、どんなどきに、どんな例外がスローされるかが一目瞭然です。クライアント側では、tryとcatchで例外発生時のプログラムの処理をかき分けることができるので、コードもすっきりします。

また後日触れることにもなりますが、単体テストのコードを書く際も、異常系の場合に発生する例外がはっきりしていれば、テストコードもすっきりします。

異常系の場合、falseや空文字、null、0などをreturnしてしまいがちですが、それを判定して条件分岐する際、厳密な比較ができないと思わぬ誤作動に繋がります(数字の0と文字列としての”0″のどちらも返してしまう可能性のあるメソッドの場合など)。それであれば例外投げたほうがクライアント側の判定処理はかなり楽です。

@todo

これもよく使います。なんてことはないただのメモ帳代わりなのですが、phpdocはtodoだけを集めてリスト化してくれます。なのでなんでも思いついた時にtodoに入れていけば、忘れることが無くなります。後日きちんとした形でメモを残したければ別途redmineのチケットなどにしておきます。

マークダウンについて

本文はマークダウン形式で記述することができます。
github形式のmarkdownに対応しているようです。
見た目の調節がうまくいかないときは確認してみましょう。
こちらで分かりやすく紹介されています。

https://gist.github.com/wate/7072365

ドキュメントの生成方法

こちらも基本的なことはいろいろなところで紹介されているので割愛します。

ドキュメント化することのメリット

ドキュメントを作成するメリットとして、あとからプログラムを見返してみてどういう仕様だったのかを簡単に確認できるということは当然あるのですが、もうひとつ「客観的に自分の書いたプログラムを見られる」というのが大きいと感じました。

例えば内部でソート関数を使ってソートしているメソッドのドキュメントを書いていると、「昇順でしか返せないのかよ・・・」と、自分でツッコミを入れたくなります。

それであれば、引数でそのメソッドを拡張できるようにしたら便利だということに気づくわけです。特にメソッド内でデータなどをハードコードしていたり、委譲するクラスを内部で決め打ちしていたりする場合、引数で少し柔軟にしてあげると、格段に使いやすくなります。

他にもいろんな処理を詰め込み過ぎてメソッドが肥大化し、いざドキュメントを書こうとしても一体何をするメソッドなのかを説明できない場合があります。大概そういった場合はいくつかのメソッドに分割できますし、そのほうがあとあと再利用もしやすいし、テストコードも書きやすくなります。

このように、ドキュメントを書いていく過程で、メソッドやクラス構成の問題点に気づき、リファクタリングプロセスが正しく働きます。

今後は弊社でのPHPUnit、Phing、Jenkinsの導入方法と運用形態や、コーディング規約、PSR、namespaceなどについて書いていきたいと思います。