分Step4:クラスに分割するそれではいよいよクラスの分割です。ここでは一時変数のrowIndexに注目します。メソッドを見ると,rowIndexは1で宣言されて,23のループの中でインクリメントされながら使われています。変数が使用されている範囲はbuildDocumentメソッドの全体に渡っていて,その間XMLを生成するときに必要な現在行の状態を保持しています。このように,長い範囲で使用されるローカル変数があると,リファクタリングが行いにくくなるという問題があります。組織要素,ユーザ要素の追加を別メソッドにする場合,それぞれのメソッドでの行の増分をrowIndexに足したり,現在のrowIndexを渡したりする必要があります。メソッド呼び出し,戻しの際に「状態を引き継ぐ」必要が出てくるのです。このような「状態を表すローカル変数」は,まずその処理自体をクラスに抽出します。次に「状態を表すローカル変数」をフィールド変数に移動することで,メソッド間の状態の引き継ぎを一掃でき,後のリファクタリングが行いやすくなります。クラスを抽出した結果はリスト6,図4です。XmlBuilderという名前のクラスを作成してnewして使用しています(1⁠)⁠。rowIndexはXmlBuilderクラスのフィールド変数に移動しています(2⁠)⁠。createDivisionsNodeメソッド(4⁠)⁠,createUsersNodeメソッド(3)で組織,ユーザの要素を作成していますが,rowIndexがフィールド変数となっているのでこのリファクタリングが可能になりました。引数でrowIndexを渡したり,増分を戻したりする必要はありません。使用するメソッドは,XmlBuilderクラスに移動しています。最終的にすべての変数のスコープとメソッドが「本当にその変数が必要な範囲」と一致するようにリファクタリングされて整理されました。変数やメソッドが必要な範囲は明確になり,メンテナンスが行いやすい状態になっています。考察1:XmlBuilderクラスをインナークラスとして実装しているのはなぜ?クラス内にクラスを宣言するインナークラスは使い出すとかなり便利です。今回のように特定の場所だけで使用される処理のインナークラスによる実装には,次のメリットがあります。実際に使用される個所のすぐ近くにクラスがあるのでわかりやすいアクセスレベルをprivateにすることで,ほかのクラスから利用させないようにできます。privateにするのがよいでしょう。元のクラスとの依存関係をstaticで制御できるstaticなインナークラスにすると元のクラスのフィールド変数にはアクセスできませんが,その分依存が少ないクラスになります。staticを外すともとのクラスのフィールド変数にアクセスできます(注13⁠)⁠。ケースバイケースで使い分けるとよいでしょう。新しいファイルを増やさなくてよい初心者のころは新しいクラスを作成するのは勇気のいることです。新しいファイルを増やすとなんだかリーダーに怒られるんじゃないか?と心配になる人もいるんじゃないかと思います。インナークラスなら新しいファイルを増やす必要がないので,気軽にクラスを作れるようになります。本来インナークラスか否か?というのは,技術的な判断で決定されるべきです。現実的に人がプログラミングするので,このような心理的なメリットは十分大きいと筆者は考えます。まとめると,外部向けにクラスを作るほどおおげさではないけど,状態を保持する自分都合のクラスを作りたくなったら,インナークラスがお勧めです。注13)前号の本連載第3回「スコープを意識したプログラミング」の「インナークラス」の項も合わせてご覧ください。考察2:divs,usersをコンストラクタで渡しているのはなぜ?リスト63のXmlBuilderのコンストラクタは組織とユーザ情報のリストが引数になっています。これは,XmlBuilderからdivisionService,userServiceへの依存をなくし,テスタビリティを高めるのが目的です。このようにしておけば,テスト用の組織とユーザのリストをコンストラクタで渡すことで,簡単にXmlBuilderをテストできます。staticなクラスとして宣言しているのは,XmlBulilderからXmlApiActionのフィールド変数であるdivisionService,userServiceへのアクセスを防ぐためです。考察3:フィールド変数になりそうなものクラスを抽出した際にフィールド変数として保持したほうがよいものとしては,フラグや状態を表す変数,いくつかのインスタンスメソッドで使用するデータ,いくつかの値をセットで扱う必要がある変数などがあります。考察4:これからどうする?ここからの発展系としては,ローカル変数docをフィールド変数に移動して,引数からdocをなくすこともできます。こちらは本誌Webサイトからの配布用のサンプルコードに「Step5Action」として含まれていますので,興味がある人はそちらもご覧ください。今回のまとめ今回は処理の分割について考えていきました。メソッド分割やクラス分割に答えはありませんが,試行錯誤することで,勘所は必ずつかめてきます。本稿が「メソッド分割やクラス分割って気軽にやってもいいんだ!」という考えのきっかけになれば幸いです。今まで,連載では「名前付け」「⁠スコープ」「⁠コードの分割」という順番で「良いコード」の基本的な要素について扱ってきました。次回は少し趣向を変えて,「⁠プログラムを作成するプログラム⁠」⁠,メタプログラミングについての話です。著者プロフィール縣俊貴(あがたとしたか)学生時代にMSXで制限された環境でのプログラミングの楽しさを学ぶ。以来,オープンソースのWiki実装「MobWiki」の開発や受託開発などを経て,現在はプロジェクト管理ツール「Backlog」,ドローツール「Cacoo」など,コラボレーション型のWebサービスの企画と製品開発を行う。2019」を開催しました。DAY1・DAY2の様子を注目セッションとともにお伝えします。LINEのエンジニア3名がイベントに先駆けて見どころを紹介します。コードの安全性・安定性を高める開発サイクル~テスト管理の効率を上げ,脆弱性診断を自動で行う~本連載では,連載「業務を改善する情報共有の仕掛け」を受けつつ,安全性・安定性を加えた開発サイクルについて考えていきます。若者世代から圧倒的な人気を誇るライブ配信&動画投稿コミュニティアプリ「MixChannel」(ミクチャ)の裏側(レコメンドシステムやサーバサイド開発など)について解説していきます。その他の連載CSS3アニメーションでつくるインターフェイス表現CSS3によるアニメーション表現を紹介していきます。その中でも,幅広い読者に応用してもらえるだろうインターフェイスを主なお題とします。MySQL道普請便り本連載では,MySQLを使ったアプリ開発・運用に関するノウハウをご紹介していきます。RecipeUbuntuの強力なデスクトップ機能を活用するための,いろいろなレシピをお届けします。JavaScriptセキュリティの基礎知識JavaScriptに関するセキュリティ上の問題はどこで発生し,どうすれば防ぐことができるのか?について解説していきます。〜システムをきちんと運用するための基礎知識システムは「作って終わり」ではなく,運用の中でさまざまな問題が発生します。問題の発生に備えて事前にどのような対応をしておくべきなのか,問題発生時に何をしなければならないのか,ポイントを解説していきます。きたみりゅうじの聞かせて珍プレーソフトウェア開発の現場で体験したトホホな失敗,思わずうなる珍プレーをきたみりゅうじ氏が四コママンガで紹介。Linuxのメンテナンスの傍ら,Linuxやオープンソースソフトと日々を過ごす著者が,その魅力とつきあい方を,エッセイ風味でお届けします。PRESS特別編集部員,さわやか笑顔のスーパーハカーはまちちゃんとネット大好き14歳わかばちゃんが,毎号,読者の皆さんから寄せられたおたよりを紹介します。皆さんの日頃の悩みにも答えちゃいますよ。]メールでのお知らせメールで次の案内をお送りしております。メールの配信を希望する方は,利用したい項目をチェックしてメールアドレスを入力し,[登録]ボタンをクリックしてください。UPDATES[ほぼ週間に1回]新刊メールマガジン[ほぼ週間に1回]電脳会議の各号案内[ほぼ1ヵ月半に1回]※変更する場合や停止する場合は,登録情報変更ページをご覧ください。※登録いただいたメールアドレスには,そのお知らせ以外,配信いたしません。Ltd.ページ内容の全部あるいは一部を無断で利用することを禁止します。個別にライセンスが設定されている記事等はそのライセンスに従います。