(57)【要約】【課題】  プログラム設計変更における情報隠蔽作業を自動化する。【解決手段】  入力されたプログラムにおける変数のうち、ユーザに指定された変数の生存範囲を算出する生存範囲算出部２と、ユーザに指定された変数の被覆メソッドを算出する被覆メソッド算出部３と、新規クラスの抽出が必要か否かを判定するクラス抽出判定部４と、上記ユーザに指定された変数を、上記被覆メソッドまたはその上位にあるメソッドの局所変数とする局所変数化実行部５と、上記入力されたプログラムから新規クラスを抽出し、上記指定された変数をその新規クラスのメンバ変数とし、上記指定された変数にアクセスするメソッドを上記新規クラスに移動するクラス抽出実行部６と、上記新規クラスのインスタンスを、上記被覆メソッドまたはその上位にあるメソッドの局所変数とするインスタンス配置部７と、を備えている。【選択図】  図１
2006201981.tif 000002
【特許請求の範囲】
【請求項１】
入力されたプログラムの情報隠蔽を行う情報隠蔽装置であって、
上記入力されたプログラムにおける変数のうち、ユーザに指定された変数が生存期間中に実際に生存している範囲である生存範囲を算出する生存範囲算出手段と、
上記生存範囲中における手続きのうち、最上位の手続きである被覆手続きを算出する被覆手続き算出手段と、
上記入力されたプログラムから新規クラスの抽出が必要か否かを判定するクラス抽出判定手段と、
上記指定された変数を、上記被覆手続きまたはその上位にある手続きの局所変数とする局所変数化実行手段と、
上記入力されたプログラムから新規クラスを抽出し、上記指定された変数をその新規クラスのメンバ変数とし、上記指定された変数にアクセスする手続きを上記新規クラスに移動するクラス抽出実行手段と、
上記新規クラスのインスタンスを、上記被覆手続きまたはその上位にある手続きの局所変数とするインスタンス配置手段と、
を備えていることを特徴とする情報隠蔽装置。
【請求項２】
上記クラス抽出判定手段は、上記被覆手続きが上記指定された変数にアクセスしないか否かに基づき、クラス抽出が必要か否かを判定することを特徴とする請求項１に記載の情報隠蔽装置。
【請求項３】
上記クラス抽出判定手段は、入力データに設定された、クラス抽出を行うか否かを示すフラグに基づき、クラス抽出が必要か否かを判定することを特徴とする請求項１に記載の情報隠蔽装置。
【請求項４】
上記局所変数化実行手段は、上記指定された変数を、上記被覆手続きまたはその上位にある手続きのうち、ユーザに選択された手続きの局所変数とすることを特徴とする請求項１ないし３のいずれか１項に記載の情報隠蔽装置。
【請求項５】
上記クラス抽出実行手段は、さらに、ユーザに指定された手続きを上記新規クラスに移動するものであることを特徴とする請求項１ないし４のいずれか１項に記載の情報隠蔽装置。
【請求項６】
入力されたプログラムの情報隠蔽を行う情報隠蔽方法であって、
上記入力されたプログラムにおける変数のうち、ユーザに指定された変数が生存期間中に実際に生存している範囲である生存範囲を算出する第１ステップと、
上記生存範囲中における手続きのうち、最上位の手続きである被覆手続きを算出する第２ステップと、
上記入力されたプログラムから新規クラスの抽出が必要か否かを判定する第３ステップと、
上記指定された変数を、上記被覆手続きまたはその上位にある手続きの局所変数とする第４ステップと、
上記入力されたプログラムから新規クラスを抽出し、上記指定された変数をその新規クラスのメンバ変数とし、上記指定された変数にアクセスする手続きを上記新規クラスに移動する第５ステップと、
上記新規クラスのインスタンスを、上記被覆手続きまたはその上位にある手続きの局所変数とする第６ステップと、
を備えていることを特徴とする情報隠蔽方法。
【請求項７】
請求項６に記載の情報隠蔽方法における各ステップをコンピュータに実行させるための情報隠蔽プログラム。
【請求項８】
請求項７に記載の情報隠蔽プログラムを格納したことを特徴とするコンピュータ読み取り可能な記録媒体。
【請求項９】
入力されたプログラムの情報隠蔽を行う情報隠蔽装置であって、
上記入力されたプログラムにおける変数のうち、ユーザに指定された変数が生存期間中に実際に生存している範囲である生存範囲を算出する生存範囲算出手段と、
上記生存範囲中における手続きのうち、最上位の手続きである被覆手続きを算出する被覆手続き算出手段と、
上記入力されたプログラムから新規モジュールの分離が必要か否かを判定するモジュール分離判定手段と、
上記指定された変数を、上記被覆手続きまたはその上位にある手続きの局所変数とする局所変数化実行手段と、
上記入力されたプログラムから新規モジュールを分離し、上記指定された変数をその新規モジュールの大域変数とし、上記指定された変数にアクセスする手続きを上記新規モジュールに移動するモジュール分離実行手段と、
を備えていることを特徴とする情報隠蔽装置。
【請求項１０】
入力されたプログラムの情報隠蔽を行う情報隠蔽方法であって、
上記入力されたプログラムにおける変数のうち、ユーザに指定された変数が生存期間中に実際に生存している範囲である生存範囲を算出する第１ステップと、
上記生存範囲中における手続きのうち、最上位の手続きである被覆手続きを算出する第２ステップと、
上記入力されたプログラムから新規モジュールの分離が必要か否かを判定する第３ステップと、
上記指定された変数を、上記被覆手続きまたはその上位にある手続きの局所変数とする第４ステップと、
上記入力されたプログラムから新規モジュールを分離し、上記指定された変数をその新規モジュールの大域変数とし、上記指定された変数にアクセスする手続きを上記新規モジュールに移動する第５ステップと、
を備えていることを特徴とする情報隠蔽方法。
【請求項１１】
請求項１０に記載の情報隠蔽方法における各ステップをコンピュータに実行させるための情報隠蔽プログラム。
【請求項１２】
請求項１１に記載の情報隠蔽プログラムを格納したことを特徴とするコンピュータ読み取り可能な記録媒体。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、入力されたプログラムの情報隠蔽を行うための情報隠蔽装置、情報隠蔽方法、情報隠蔽プログラム、およびコンピュータ読み取り可能な記録媒体に関する。
【背景技術】
【０００２】
プログラムの外的振る舞いを保ったままソースコードの内部構造を変更することをリファクタリング（非特許文献４、非特許文献１０〜１２参照）という。リファクタリングは、主にソースコードの可読性や再利用性の向上のために実施され、とりわけ自動リファクタリングは、煩雑な手作業を自動化し、さらに不具合の非混入が保証されていることから、開発の効率と信頼性の双方を向上させる技術として注目を集めている。
【０００３】
自動リファクタリングは一種のプログラム変換技術と考えられるが、変換の目的がメモリの使用効率や実行速度などの最適化ではない点、変更後のソースコードがプログラマによって読まれることを前提としている点などで、コンパイラによる最適化技術と異なる。
【特許文献１】特開平１１−２３７９８４号公報（平成１１年８月３１日公開）
【非特許文献１】D. Callahan: The program summary graph and flow-sensitive interprocedural data flow analysis, In ACM SIGPLAN Conf. on Programming Language Design and Implementation (PLDI'88), ACM SIGPLAN Notices 23(7), pp.47--56, 1988.
【非特許文献２】J. D. Choi, M. Gupta, M. Serrano, V. C. Sreedhar and S. Midkiff: Escape analysis for Java, In ACM SIGPLAN Conf. on Object-Oriented Programming Systems, Languages and Applications (OOPSLA'99), 1999.
【非特許文献３】K.D. Cooper and K. Kennedy: Interprocedural side-effect analysis in linear time, In ACM SIGPLAN Conf. on Programming Language Design and Implementation (PLDI'88), ACM SIGPLAN Notices 23(7), pp.57--66, 1988.
【非特許文献４】M. Fowler: Refactoring -- Improving the Design of Existing Code, Addison-wesley, 1999.
【非特許文献５】M. Fowler, et. al.: A catalog of common refactorings, http://www.refactoring.com/catalog/index.html, 2005.
【非特許文献６】E. Gamma, R. Helm, R. Johnson and J. Vlissides: Design Patterns: Elements of reusable object-oriented software, Addison-Wesley, 1995.
【非特許文献７】W. Griswold and D. Notkin: Automated assistance for program restructuring, ACM Trans. on Software Engineering Methodologies 2(3), pp.228-269, 1993.
【非特許文献８】R. Komondoor and S. Horwitz: Semantics-preserving procedure extraction, In ACM Symp. on Principles of Programming Language (POPL'00), pp.155--169, 2000.
【非特許文献９】M. J. Harrold and G. Rothermel: Performing data flow testing on classes, In Proc. of the 2nd ACM SIGSOFT Symp. on the Foundations of Software Engneering, pp. 154--169, 1994.
【非特許文献１０】T. Mens, S. Demeyer, B. D. Bois, H. Stenten and P. V. Gorp: Refactoring: Current Research and Future Trends, Electronic Notes in Theoretical Computer Science, 82(3), 2003.
【非特許文献１１】T. Mens and T. Tourwe: A survey of software refactoring, IEEE trans. on software engineering, 30(2), pp.126--139, 2004.
【非特許文献１２】W. F. Opdyke: Refactoring Object-Oriented Frameworks, PhD thesis, University of Illinois at Urbana-Champaign, 1992.
【非特許文献１３】D. L. Parnas: On the criteria to be used in decomposing systems into modules, Comm. of the ACM, 15(12), pp.1053--1058, 1972.
【非特許文献１４】T. Reps, S. Horwitz and M. Sagiv: Precise interprocedural dataflow analysis via graph reachability, In ACM Symp. on Principles of Programming Language (POPL'95), 1995.
【非特許文献１５】L.Tokuda and D.Batory: Evolving object-oriented designs with refactorings, Automated Software Engineering, 8, pp.89--120, 2001.
【発明の開示】
【発明が解決しようとする課題】
【０００４】
しかしながら、現実の膨大な開発作業の中のどの程度の範囲でリファクタリングが有効であるかについては、いくつか事例報告（非特許文献１５参照）があるのみで、包括的な調査は今のところなされていない。既存のリファクタリングとして、たとえばFowlerは経験的に集められた72種類のリファクタリングを非特許文献４で提案しているが、これらのリファクタリングのほとんどは単純な操作系列で定義されており、これらを組み合わせるだけで現実規模の設計変更に対応できるかは疑問である。
【０００５】
特に、情報隠蔽（非特許文献１３参照）はプログラム設計において最も基本的な設計活動の１つであるが、その情報隠蔽作業を自動リファクタリング化することは従来十分な検討がなされていなかった。たとえば、特許文献１において提案されているプログラム設計支援装置は、単にメソッドを移動させることにだけ発明の着眼点がおかれており、情報隠蔽ということは考慮されていない。
【０００６】
本発明は、上記従来の問題点に鑑みなされたものであって、プログラム設計における情報隠蔽作業を自動化し得る情報隠蔽装置、情報隠蔽方法、情報隠蔽プログラム、およびコンピュータ読み取り可能な記録媒体を提供することを目的とする。
【課題を解決するための手段】
【０００７】
本発明の情報隠蔽装置は、上記従来の課題を解決するために、上記入力されたプログラムにおける変数のうち、ユーザに指定された変数が生存期間中に実際に生存している範囲である生存範囲を算出する生存範囲算出手段と、上記生存範囲中における手続きのうち、最上位の手続きである被覆手続きを算出する被覆手続き算出手段と、上記入力されたプログラムから新規クラスの抽出が必要か否かを判定するクラス抽出判定手段と、上記指定された変数を、上記被覆手続きまたはその上位にある手続きの局所変数とする局所変数化実行手段と、上記入力されたプログラムから新規クラスを抽出し、上記指定された変数をその新規クラスのメンバ変数とし、上記指定された変数にアクセスする手続きを上記新規クラスに移動するクラス抽出実行手段と、上記新規クラスのインスタンスを、上記被覆手続きまたはその上位にある手続きの局所変数とするインスタンス配置手段と、を備えていることを特徴としている。
【０００８】
上記構成によれば、生存範囲算出手段および被覆手続き算出手段により、入力されたプログラムとユーザに指定された変数とから被覆手続きを算出することができる。なお、「生存期間」とは、ユーザに指定された変数を変数vとすると、vの記憶領域がメモリ上に確保されている期間を意味している。また、「生存範囲」とは、vに記憶されている値がその後のプログラム実行に影響を与えるような実行文の系列で構成される、生存期間中の連続した一期間を意味している。
【０００９】
そして、クラス抽出判定手段において新規クラスの抽出が必要でないと判断された場合には、局所変数化実行手段により、ユーザに指定された変数を、被覆手続きまたはその上位にある手続きの局所変数とすることができる。一方、クラス抽出判定手段において新規クラスの抽出が必要であると判断された場合、クラス抽出実行手段により、ユーザに指定された変数を新規クラスのメンバ変数とするとともに上記指定された変数にアクセスする手続きを新規クラスに移動し、インスタンス配置手段により、新規クラスのインスタンスを被覆手続きまたはその上位にある手続きの局所変数とすることができる。
【００１０】
このようにして、入力されたプログラムにおける被覆手続きまたはその上位にある手続が、ユーザに指定された変数にアクセスしないようにすることができる。これにより、入力されたプログラムの情報隠蔽を行うことができる。
【００１１】
なお、クラス抽出判定手段における判定は、被覆手続きが指定された変数にアクセスしないか否かに基づき行うことにより、新規クラス抽出の必要性を正確に判断することができる。
【００１２】
また、クラス抽出判定手段における判定は、入力データに設定されたクラス抽出を行うか否かを示すフラグに基づき行ってもよい。これにより、新規クラス抽出の必要性を効率よく判断できる。
【００１３】
さらに、ユーザに指定された変数を局所変数とする手続きを、ユーザに選択された手続きとすることにより、ユーザの要求に沿った情報隠蔽を行うことができる。
【００１４】
さらに、新規クラスに移動する手続きをユーザに指定された手続きとすることによっても、ユーザの要求に沿った情報隠蔽を行うことができる。
【００１５】
また、本発明の情報隠蔽方法は、上記従来の課題を解決するために、上記入力されたプログラムにおける変数のうち、ユーザに指定された変数が生存期間中に実際に生存している範囲である生存範囲を算出する第１ステップと、上記生存範囲中における手続きのうち、最上位の手続きである被覆手続きを算出する第２ステップと、上記入力されたプログラムから新規クラスの抽出が必要か否かを判定する第３ステップと、上記指定された変数を、上記被覆手続きまたはその上位にある手続きの局所変数とする第４ステップと、上記入力されたプログラムから新規クラスを抽出し、上記指定された変数をその新規クラスの大域変数とし、上記指定された変数にアクセスする手続きを上記新規クラスに移動する第５ステップと、上記新規クラスのインスタンスを、上記被覆手続きまたはその上位にある手続きの局所変数とする第６ステップと、を備えていることを特徴としている。
【００１６】
上記構成の情報隠蔽方法によれば、第１ステップ〜第６ステップにより、本発明の情報隠蔽装置における各手段と同様の処理が実現されているので、本発明の情報隠蔽装置と同様の作用効果を得ることができる。
【００１７】
さらに、本発明は、以下の構成とすることにより、非オブジェクト指向言語で構成されたプログラムの情報隠蔽を行うことも可能である。
【００１８】
すなわち、本発明の情報隠蔽装置は、上記入力されたプログラムにおける変数のうち、ユーザに指定された変数が生存期間中に実際に生存している範囲である生存範囲を算出する生存範囲算出手段と、上記生存範囲中における手続きのうち、最上位の手続きである被覆手続きを算出する被覆手続き算出手段と、上記入力されたプログラムから新規モジュールの分離が必要か否かを判定するモジュール分離判定手段と、上記指定された変数を、上記被覆手続きまたはその上位にある手続きの局所変数とする局所変数化実行手段と、上記入力されたプログラムから新規モジュールを分離し、上記指定された変数をその新規モジュールの大域変数とし、上記指定された変数にアクセスする手続きを上記新規モジュールに移動するモジュール分離実行手段と、を備えている構成としてもよい。
【００１９】
また、本発明の情報隠蔽方法は、上記入力されたプログラムにおける変数のうち、ユーザに指定された変数が生存期間中に実際に生存している範囲である生存範囲を算出する第１ステップと、上記生存範囲中における手続きのうち、最上位の手続きである被覆手続きを算出する第２ステップと、上記入力されたプログラムから新規モジュールの分離が必要か否かを判定する第３ステップと、上記指定された変数を、上記被覆手続きまたはその上位にある手続きの局所変数とする第４ステップと、上記入力されたプログラムから新規モジュールを分離し、上記指定された変数をその新規モジュールの大域変数とし、上記指定された変数にアクセスする手続きを上記新規モジュールに移動する第５ステップと、を備えている構成としてもよい。
【００２０】
上記構成の情報隠蔽装置または方法によれば、入力されたプログラムにおける被覆手続きまたはその上位にある手続が、ユーザに指定された変数にアクセスしないようにすることができる。これにより、入力されたプログラムの情報隠蔽を行うことができる。
【００２１】
なお、コンピュータに上記情報隠蔽方法を実行させる情報隠蔽プログラムにより、コンピュータを用いて本発明の情報隠蔽方法と同様の作用効果を得ることができる。さらに、上記情報隠蔽プログラムをコンピュータ読み取り可能な記録媒体に記憶させることにより、任意のコンピュータ上で上記情報隠蔽プログラムを実行させることができる。
【発明の効果】
【００２２】
本発明によれば、情報隠蔽リファクタリングを自動化できるので、プログラムの設計作業におけるユーザ負担を軽減することができ、プログラムの開発効率を大幅に向上することが可能となる。
【発明を実施するための最良の形態】
【００２３】
〔１．概要説明〕
本実施形態に係る情報隠蔽装置は、変数の宣言位置を移動して情報隠蔽を行うある種の設計変更に焦点を当て、そのリファクタリングへの置き換えについて検討された研究から発明されたものである。なお、本実施形態では、情報隠蔽プログラムの対象言語がJava（登録商標）である場合について説明するが、対象言語はJavaに限られるものではない。
【００２４】
先ず、本実施形態の情報隠蔽装置１は、図１に示すように、生存範囲算出部（生存範囲算出手段）２と、被覆メソッド算出部（被覆手続き算出手段）３と、クラス抽出判定部（クラス抽出判定手段）４と、局所変数化実行部（局所変数化実行手段）５と、クラス抽出実行部（クラス抽出実行手段）６と、インスタンス配置部（インスタンス配置手段）７とを備えている。
【００２５】
生存範囲算出部２は、情報隠蔽が行われる前のプログラムPにおける変数vの生存範囲を求めるものである。なお、変数vはユーザによって指定されるものである。生存範囲を求める処理については、既存の手続き間依存性解析を利用することができ、その一例の処理について後段に詳述する。
【００２６】
被覆メソッド算出部３は、生存範囲算出部２により求められた変数vの範囲を用いて、プログラムPにおける変数vの被覆メソッドmを算出するものである。なお、被覆メソッドの定義、および被覆メソッドの算出手順については後述する。
【００２７】
クラス抽出判定部４は、プログラムPにおいてたとえばクラスAが存在している場合において、情報隠蔽を行うためにクラスAから新たなクラスを抽出する必要があるか否かを算出するものである。なお、クラス抽出の必要性を判定する理由、およびその判定手順に関しては後述する。
【００２８】
局所変数化実行部５は、クラス抽出判定部４によりクラス抽出の必要がないと判定された場合において、変数vを被覆メソッドmの局所変数とするものである。局所変数化の手順に関しても後述する。
【００２９】
クラス抽出実行部６は、クラス抽出判定部４によりクラス抽出の必要があると判定された場合において、プログラムPにおける変数vが含まれたクラスから、新規クラスを抽出するものである。クラス抽出の処理に関しては既存の処理を用いることができ、その一例の処理について後段で説明する。
【００３０】
インスタンス配置部７は、クラス抽出実行部６により抽出された新規クラスのインスタンスを、被覆メソッドmの局所変数とするものである。インスタンス配置部７における処理の詳細についても後述する。
【００３１】
上記構成により、本実施形態の情報隠蔽装置１は、自身に入力されたプログラムPを、情報隠蔽されたプログラムP'として出力するものである。
【００３２】
たとえば、図２（ａ）に示すプログラムPAに対して情報隠蔽を行う場合を想定する。この場合、本実施形態に係る情報隠蔽装置１は、図３に示すように、クラスAから新規クラスNewClassを抽出し、変数vの宣言位置をNewClassのメンバ変数（大域変数）の位置に移動して、変数vの情報をクラスAから隠蔽する。その結果、プログラムPAは、図２（ｃ）に示す情報隠蔽されたプログラムとして設計変更される。
【００３３】
本出願の発明者が、このような設計変更に着目する理由は以下の2つである.
（１）情報隠蔽は最も基本的な設計活動の1つであるが、現実の開発工程では、初期設計段階で必要な情報隠蔽を網羅的に施すことはほぼ不可能である。仮にプログラムの実装段階で付加的に情報隠蔽を行う必要が生じた場合、それを実現するためにソースコード上では一般に複雑な変換操作が要求される。したがって、そのような作業をリファクタリングとして一般化することによって、プログラム開発効率の向上が図れると期待される。
【００３４】
（２）図２（ａ）に示すプログラムから図２（ｃ）に示すプログラムに設計変更すると、クラスだけでなくそのメソッドの内容にまで立ち入っているという点で、クラス図上で追跡可能な他の多くのリファクタリングより真に複雑であると予想される。
【００３５】
ところで、図２（ａ）から図２（ｃ）へのプログラムの設計変更では変数の情報を隠蔽するために新規にクラスを抽出しているが、情報隠蔽においてクラスの抽出が必ずしも必要というわけではない。
【００３６】
たとえば、図４（ａ）に示すプログラムPBのように、変数vの生存範囲がfunc2やfunc3の中で閉じていた場合、変数vの情報をクラスBから隠蔽するには、変数vの宣言位置をそれぞれの局所変数の位置に移動するだけよい（図４（ｂ）参照）。
【００３７】
逆に、プログラムPAにおいては、１）func1は変数vの値を知る必要がない、２）func1から呼び出される複数のメソッド(func2, func3)間で変数vの情報を共有しているという2つの理由から、変数vの情報の隠蔽先として新規クラスを抽出する必要性が生じていると考えられる。
【００３８】
情報隠蔽のために新規クラスを抽出する必要があるか否かの一般的な判定条件については後述するが、このように情報隠蔽を行う場合、対象プログラムが持つ性質のわずかな差によって適用すべき操作系列を大きく変える必要性があることがわかる。
【００３９】
また、図２（ａ）から図２（ｃ）へのプログラム設計変更を既存のリファクタリングに置き換えることはできない。
【００４０】
たとえば、非特許文献４や非特許文献５の中で、新規に独立したクラスを構成するリファクタリングはクラス抽出のみであるが、プログラムPAに対しクラス抽出を適用しても、図２（ｃ）とは異なり変数vの生存期間は短縮されない（図２（ｂ）参照）。さらに、他に変数の生存期間を短縮するリファクタリングが存在しないため, クラス抽出と他のリファクタリングとを組み合わせても、図２（ｃ）と同一の結果を得ることはできない。
【００４１】
また、図２（ａ）に示すものから図２（ｂ）に示すものへのプログラム変更と、図２（ｂ）に示すものから図２（ｃ）に示すものへのプログラム変更とを独立した２つの変換として分離し、図２（ｂ）に示すものから図２（ｃ）に示すものへのプログラム変更を新たなリファクタリングとして定義しようとしても、それは図２（ａ）に示すものから図２（ｃ）に示すものへのプログラム変更を一貫したリファクタリングとして定義することに較べてむしろ複雑かつ非効率的になることがわかる。
【００４２】
すなわち、図２（ａ）に示すものから図２（ｃ）に示すものへのプログラム変更は、その作業をこれ以上分割することが難しいと考えた方が自然である。
【００４３】
このように、情報隠蔽のために変数の宣言位置を移動するような設計変更は、従来の単純な操作系列で定義されたリファクタリングの組み合わせによって対処することが難しい本質的に複雑な作業であるといえる。そこで、本実施形態では以上のような操作体系の全体を新たなリファクタリング（情報隠蔽）として定義する。
【００４４】
ところで、情報隠蔽リファクタリングでは変換全体の正しさが各操作間の相互関係によって保証されるため、各操作単位でテストを繰り返して変換の正しさを維持するようなテスト駆動型のアプローチが適合しない。したがって、情報隠蔽リファクタリングでは、自動化によって変換全体の正当性を保証することが重要となる。なお、上記自動化にあたっては手続き間生存性解析技術を用いる。
【００４５】
本実施形態の情報隠蔽装置１により自動化された情報隠蔽リファクタリングの手続きの概略は以下のようになる。
【００４６】
（１）  指定した変数の手続き間生存性解析を行い、局所変数として再定義可能な移動先を求める
（２）  （１）の結果を元に新規にクラスを抽出する必要があるかどうかの判断を行い以下の（３）または（４）のステップへ
（３）  もし必要がなければ、指定した変数を（１）で求めた位置の局所変数として再定義し終了
（４）  新規にクラスを抽出する必要があれば、以下の処理（４−１）（４−２）を実行
（４−１）指定した変数を新規クラスのメンバ変数とし、必要なメソッドを新規クラスに移動
（４−２）新規クラスのインスタンスを（１）で求めた位置で生成するようにし終了。
【００４７】
また、情報隠蔽リファクタリングの有用性とは独立に、本実施形態の情報隠蔽装置１の意義として以下のものを挙げることができる。
【００４８】
（１）各リファクタリングを単純な操作系列で与えることは、変更内容の理解容易性や各変更のテストによる信頼性維持を実現する上では有効であるが、一方で、より現実的な設計変更を扱う上で不適切な場合があることを示した
（２）複雑なリファクタリングでは変換の途中で意味あるテストを実行することが困難であるため、変換作業全体の自動化が必須となる。このようなリファクタリングを自動化する上で、プログラムの静的解析技術が有効であることを示した
（３）情報隠蔽は最も基本的な設計活動であるにもかかわらず、本実施形態のリファクタリングが示すように、ソースコード上では比較的複雑な操作が要求される。これは既存のオブジェクト指向言語のある種の設計上の限界を示唆しているとも考えられる。
【００４９】
以下の記載では、先ず、プログラムのモデル化に関する定義を説明した後、手続き間生存性解析法およびそれを利用した生存範囲の計算法を説明し、それらの結果を利用して情報隠蔽リファクタリングを自動化する方法を説明する。また、自動化した情報隠蔽リファクタリングの計算量についても説明する。さらに、情報隠蔽リファクタリングの応用についても説明する。
【００５０】
〔１−１．関連研究〕
静的解析技術を応用した自動リファクタリングとしては, 手続き抽出(メソッド抽出とも呼ばれる、非特許文献７または非特許文献８参照)がよく知られている。本実施形態の情報隠蔽装置が対象としているリファクタリングは手続き抽出とは異なるが、手続き抽出と組み合わせることで、より抽象度の高い構造変更を提供できる可能性がある（詳細は後述する）。
【００５１】
また、本実施形態の情報隠蔽装置による情報隠蔽リファクタリングは、クラス抽出の一般化と捉えることができる。すなわち、クラス抽出は、プログラムの構造上の理由で生存期間が短縮できない特別な場合での本実施形態の情報隠蔽リファクタリング動作に相当する。
【００５２】
クラス抽出に対して本実施形態の情報隠蔽リファクタリングが有する最大のアドバンテージは、オブジェクト指向の特長を生かしている点にある。クラス抽出では、抽出したクラスのインスタンスが唯一で、その生存期間が抽出元インスタンスの生存期間とちょうど一致する。したがって、クラスの抽出は、非オブジェクト指向言語におけるモジュールの分離ともみなすことができる。
【００５３】
これに対し、本実施形態の情報隠蔽リファクタリングでは、新規クラスが抽象データ型として元のクラスから分離され、たとえば図５のように新規クラスのインスタンスが必要に応じてソース上に複数個配置される。
【００５４】
〔２．プログラムのモデル化に関する諸定義〕
プログラムPのクラス全体からなる集合をClassP、メソッド全体からなる集合をMethodPで表す。各メソッドm∈MethodPが所属するクラスを、belongsp(m)で表す。各クラスc∈ClassPが持つメンバ変数全体からなる集合を、memberP(c)で、各メソッドm∈MethodPが持つ局所変数全体からなる集合、および仮引数全体からなる集合を、それぞれ、localP(m),
argP(m)で表す。ただし、一般性を失うことがないようプログラムP中の各変数名はすべて異なるとする。また、プログラムPのメンバ変数および局所変数全体からなる集合を、VPで表す。なお以下では、文脈から明らかな場合Pの添え字の記載を省略することもある。
【００５５】
メソッドmにおいて観測可能な変数の集合visible(m)は、
visible(m)＝local(m)∪arg(m)∪member(belongs(m))
で与えられる。
【００５６】
また、変数vに対し、メソッドおよびクラスの集合
｛m∈Method｜v∈visible(m)｝∪｛c∈Class｜v∈member(c)｝
を変数vのスコープと呼び、scope(v)で表す。
【００５７】
必要に応じて各クラスCを、クラス制御フローグラフ(Class control flow graph、以下「CCFG」、非特許文献９参照）で表現する。
【００５８】
CCFGは、5項組G＝（N,NF,ET,EC,λ)で表される有向グラフで, それぞれの要素は、
N；クラス内の実行文全体からなる集合,
NF；フレーム内の実行文全体からなる集合(詳細は後述,ただしNF⊆Nとする)
ET⊆N×N；メソッド内の制御フロー
EC⊆N×N；メソッド間の制御フロー(メソッド呼び出しおよび復帰, ただしET∩ECは空集合)
λ：N→{Entry,Exit,Call,ReturnSite,Simple};実行文の種類
に対応する。
【００５９】
ここで、Entry,Exit,Simpleは、それぞれ、各メソッドの実行開始文,return文,メソッド呼び出しを伴わない実行文を表す。なお、メソッド呼び出しを行う実行文に対しては、便宜上、呼び出し直前の頂点Callと復帰後の頂点ReturnSiteとの2つの頂点に分けて表す。
【００６０】
ここで、プログラムPAをCCFGで表現したものを、図６に示す。図６に示されるプログラムPAはJava の構文規則を満たすものである。つまり、プログラムPAは、各メソッド毎に、ちょうど１つのEntry頂点(開始頂点)と、１つ以上のExit頂点(終了頂点)とを持つ。
【００６１】
ETはtransfer edgeと呼ばれ、メソッド内の制御の流れを表す。Exit頂点から出るtransfer edgeおよびEntry頂点に入る transfer edge は存在せず、Call頂点から対応するReturnSiteに向かって transfer edge がちょうど１つ存在する。
【００６２】
他の頂点から出る transfer edge は１つ以上存在し、複数のtransfer edgeが出ている場合は条件分岐を意味する。一方、ECは call/return edge と呼ばれ、メソッド間の制御の流れを表す。
【００６３】
呼び出し元のCall頂点から呼び出し先メソッドのEntry頂点と、呼び出し先メソッドのExit頂点から呼び出し元のReturnSite頂点とには、それぞれcall/return edgeが存在する。各頂点n∈Nから transfer edge のみを使って到達可能な頂点全体からなる集合をR(n)で表す。メソッドmのEntry頂点をnmとしたとき、R(nm)はそのメソッド内の実行文全体を表す。
【００６４】
また、CCFGは、特別なメソッド, フレームを持つ。フレームは、クラスCの外部環境を抽象化したメソッドであり、フレームからは、クラスCのpublic属性を持つすべてのメソッドm1,…,mkが任意の順番で呼び出される。
【００６５】
また、フレームの実行文全体からなる集合をNFで表す。NFは、Entry,Exit,Simple,Call,ReturnSite頂点をそれぞれ1つずつ持つ。
【００６６】
Transfer edgeは、Entry頂点からSimple頂点,Simple頂点からExit頂点,Simple頂点からCall頂点,Call頂点からReturnSite頂点,ReturnSite頂点からSimple頂点に向かう位置にそれぞれ存在する。Call,ReturnSite頂点と各publicメソッドとの間で、call/return edge が存在する。
【００６７】
また、必要に応じて各頂点nに対し、nで定義される変数の集合および参照される変数の集合を、それぞれ、def(n),use(n)で表す。たとえば、頂点nに対応する実行文が
''a＝o.m(b);'' であった場合、
def(n)＝{a},use(n)＝{o,b}となる。
【００６８】
〔３．情報隠蔽リファクタリング〕
情報隠蔽は、指定した変数の情報を、その情報を必要としないクラスまたはメソッドのスコープから除外するリファクタリングである。これは指定した変数のスコープを最小化する操作と言い換えることもできる。
【００６９】
スコープは、変数が局所変数である場合は所属するメソッド内に限定され、また変数がメンバ変数である場合は所属するクラス内に限定される。したがって、スコープの最小化は、変数の宣言位置を、特定メソッド内または新たに作成したクラス内へ移動することによって実現される。
【００７０】
特に、新規に作成したクラス内へ変数の宣言位置を移動する操作は、クラス抽出と一致する。一方、変数の宣言位置を移動して特定メソッド内の局所変数とする操作を、本明細書では局所変数化と記載する。
【００７１】
なお、クラス抽出をわずかに拡張することで、常にスコープを最小化する操作をクラス抽出の範囲内で定義することが可能であるが、本実施形態では以下の２つの理由から、クラス抽出とともに局所変数化も情報隠蔽における操作の選択肢として用いる。
【００７２】
（理由１）
あるプログラムの変数に対して、クラス抽出と局所変数化とが同じようにスコープを削減するならば、局所変数化を行う方が操作として単純かつソースコード全体への影響も少ないことから望ましい。
【００７３】
（理由２）
クラス抽出では変数の生存期間が短縮されないが、局所変数化ではスコープと共に生存期間も短縮することができる。生存期間の短縮は情報隠蔽の直接の目的ではないが、たとえば生存期間の短縮を伴わないクラス抽出は、非オブジェクト指向言語におけるモジュールの分離と同等の操作でしかなく、オブジェクト指向の特質を十分生かしているとは言い難い。クラスを抽出するとともにそのインスタンスの生存期間も短縮することによって、初めてクラスの抽象データ型としての機能を使うことができる。たとえば、図７に示すものからから図５に示すものへのプログラム変換では、変数counterに対して隠蔽が行われるが、抽出されたクラスNewClassは２つのインスタンスn1,n2を持っている。これは、NewClassのインスタンスの生存期間がメソッドm2()およびm3()の範囲内にそれぞれ短縮されることによって可能となったものである。
【００７４】
以上の理由から、本実施形態では、情報隠蔽リファクタリングにおける最適な操作を、指定した変数のスコープと生存期間との両方を最小化する操作と仮定し、その上でリファクタリングの自動化について説明する。それと同時に、ユーザにより多くの選択肢を提供できるよう、半自動リファクタリングを構成する方法についても後述する。
【００７５】
以下では、自動/半自動リファクタリングに共通する手続き間生存性解析について説明する。
【００７６】
〔３−１．生存期間の短縮〕
変数vの生存期間を、意味を保存したままどこまで短縮できるかは、変数vの生存性を解析することによって求めることができる。以下では、生存期間の中で変数が実際に生存している範囲(生存性解析によって求められる)を生存期間に対して生存範囲とよぶ。
【００７７】
たとえば、図４（ａ）および図４（ｂ）に示すプログラム変換においては、変数vの生存範囲が、func2内およびfunc3内でそれぞれ閉じているため、変数vをfunc2およびfunc3の局所変数として再定義することが可能である。
【００７８】
これに対し、図２（ａ）および図２（ｃ）に示すプログラム変換においては、変数vがPA中で、func1中のfunc2の呼び出しからfunc3の呼び出しまで生存しているため、変数vの意味を保ったまま、生存期間をfunc2やfunc3の呼び出し内にまで生存期間を縮小することができない。
【００７９】
〔３−１−１．手続き間生存性解析〕
情報隠蔽リファクタリングでは、複数手続き(メソッド)にまたがる生存性の解析が必要とされる。手続き間生存性解析としては、特に省メモリの観点からさまざまな解析法が提案されており、たとえばエスケープ解析（非特許文献２参照）では、呼び出し先で生成されたオブジェクトが復帰後も使用されるか否かを解析し、使用されない場合、オブジェクトのイメージをスタック領域に確保することで省メモリ化を図る。しかし、エスケープ解析は本実施形態における手続き間生存性解析と以下の点で内容が異なる。
【００８０】
（１）情報隠蔽リファクタリングでは、変数の生存性解析のみが必要であって、オブジェクトイメージの生存性解析は不要である。
【００８１】
（２）情報隠蔽リファクタリングでは、単に呼び出し先から値が返されるか否かだけでなく、復帰後その値が実際に使用されるか否かの情報まで必要である(live on exit)。
【００８２】
比較のため、たとえば以下に示すようなプログラムを考える。
【００８３】
【数１】
2006201981.tif 000003
【００８４】
ここで、メソッドM1からの復帰後、メンバ変数bへのアクセスはないものとする。このとき、エスケープ解析では、L1, L2, L3 で生成されたクラス B, C のそれぞれのオブジェクトイメージを、メソッドM1からの復帰時に残しておく必要があるかどうかを調べる。ここでは、L2で生成されたBのオブジェクトイメージのみが、復帰後利用される可能性があると判断され、ヒープ領域に残されることになる。
【００８５】
これに対して、本実施形態の生存性解析で必要とされるのは、左辺値、すなわちオブジェクトへの参照の手続き間の生存性である。たとえば、bは復帰後使用されることがないため、メソッドM1内の局所変数として宣言し、''L2:B b ＝ new B();''と書換えてもかまわない。その結果、L2で生成されたBのオブジェクトイメージはエスケープしなくなる。
【００８６】
なお、他の手続き間解析法として、たとえば非特許文献１４などのデータフロー関数に基づく解析法を挙げることができるが、これらはプログラムの実行順序に対して順方向の解析法であり、本質的に逆方向の解析を必要とする生存性解析には適合しない。そこで、本実施形態では、大域変数に対する伝統的な手続き間解析（非特許文献１、非特許文献３）を応用して、生存性解析を行う。
【００８７】
ただし、ここでは解析対象をあるクラスCに固定し、クラスCのprivateメンバ変数を大域変数とみなして、クラスCのメソッド間での解析を行う。なお、クラス内解析に関しては非特許文献９を参照されたい。
【００８８】
また、一般的に生存性の厳密解を求めることは困難であるため、本実施形態でも安全サイドでの近似解を求める(may-live 解析)。また、本実施形態では、解析にクラスCのCCFGによる表現を用いる。Kill,Useのデータフロー方程式は、非特許文献１で紹介されているものを用いる。
【００８９】
CCFGの各頂点をnとしたときに、Kill(n)は、n以降に必ず値が定義されるメンバ変数の集合、Use(n)はn以降で定義される前に参照される可能性があるメンバ変数の集合を表す。なお、Killは以下の方程式を満たす最大不動点として、Useは以下の方程式を満たす最小不動点としてそれぞれ定義される。
【００９０】
【数２】
2006201981.tif 000004
【００９１】
【数３】
2006201981.tif 000005
【００９２】
本実施形態では、KillおよびUseを用いて、各頂点で生存している変数の集合Liveを以下の方程式を満たす最小不動点として定義する。UseとLiveの本質的な違いは、あるメソッドmの呼び出しnにおいて、Use(n)ではmの呼び出し内部での変数の使用および定義のみを調べればよいのに対し、Live(n)ではmの呼び出し後の使用および定義の情報まで調べる必要がある点である。
【００９３】
したがって、Liveの定義は、文脈に依存する形式になっている。
【００９４】
【数４】
2006201981.tif 000006
【００９５】
各方程式が満たす解は標準的な繰り返しアルゴリズムで求める。KillおよびUseを求めるアルゴリズムは、非特許文献１を参照されたい。また、Liveを求めるアルゴリズムを図８に示す。
【００９６】
〔３−１−２．被覆メソッド〕
変数隠蔽リファクタリングの準備として、前節で計算した生存性Liveを元に、以下のように被覆メソッドを定義する。すなわち、変数v∈Vおよびメソッドm∈Methodについて、m中のある頂点nについてv∈Live(n)が成り立ち、かつmの開始頂点nENTおよびすべての終了頂点nEXTについて、vがLive(nENT)に属しておらず、なおかつvがLive(nEXT)に属していないときに限り、mはvの生存期間を被覆するといい、mをvの被覆メソッドという。
【００９７】
たとえば図７のプログラムにおいて、メンバ変数counterは先頭に'*'で記した実行文で生存している。したがって、図７に示すプログラム中で、メンバ変数counterの被覆メソッドは、m2()およびm3()となる。
【００９８】
なお、メンバ変数の宣言位置を各被覆メソッド内の局所変数の位置に移動することによって生存期間を最小化することができる。被覆メソッドの情報は、後述するように生存期間の短縮だけでなく、新規クラスの抽出が必要であるか否かを判断する材料としても利用される。
【００９９】
〔３−２．自動情報隠蔽リファクタリング〕
〔３−２−１．アルゴリズム〕
上述したように、情報隠蔽リファクタリングにおける最適な操作を、指定した変数のスコープおよび生存期間を同時に最小化する操作と仮定する。以下の記載では、その仮定の下で情報隠蔽リファクタリングを自動化する方法について説明する。なお、本実施形態では指定できる変数をprivateメンバ変数のみとするが、その他の種類の変数を指定してもよい。
【０１００】
変数の生存期間は基本的に、上述した手順で求められた被覆メソッドの呼び出しの範囲内にまで短縮することができる。しかし、生存期間内に通過するすべてのメソッドが、その変数の値を知る必要はない。
【０１０１】
たとえば、図７に示すプログラムでは、変数counterの２つの生存範囲の中を、それぞれメソッドm2()およびm3()が通過しているが、これらのメソッドはいずれもcounterの値を直接知る必要がない。
【０１０２】
したがって、生存期間を最小化するために、変数counterをその被覆メソッドであるm2()およびm3()の局所変数として単純に局所変数化すると、変数counterのスコープには、不必要なメソッドm2(),m3()が含まれることになる。
【０１０３】
そこで, 新しいクラスNewClassを抽出し、実際にcounter にアクセスしているメソッドopen(),read(),close()のみを、counterとNewClass内でカプセル化することによって、メソッドm2()およびm3()を、変数counterのスコープから除外する。このとき、NewClassの各インスタンスn1,n2をm2()およびm3()の内部でそれぞれ宣言すれば、インスタンスn1およびn2に含まれる変数counterの生存期間も同時に最小化することができる（図５参照）。
【０１０４】
新規クラスの抽出は、比較的大きなソースコードの改変であるため、必要のない限り避けるべきであると考える。変数vのスコープと生存期間の両方を短縮する上で新規クラスCの抽出が必要となる条件は、変数vのすべての被覆メソッドがvにアクセスしないことで与えることができる。
【０１０５】
なぜなら、被覆メソッドmが変数vにアクセスしなければ、新規クラスCを抽出し、クラスC内で変数vとカプセル化するメソッドからmを外すことで、変数mをvのスコープに含めないことができるからである。逆に、変数vのある被覆メソッドmがvにアクセスする場合、以下の２つの操作が競合するため、クラスCを抽出してもvの生存期間とスコープの両方とを最小化することができない。
【０１０６】
（操作１）生存期間を短縮するためにCのインスタンスを被覆メソッドmの中で宣言する
（操作２）スコープを削減するため、vにアクセスするメソッドmをCに移動する。
【０１０７】
以上の説明に基づけば、情報隠蔽リファクタリングは、以下のフローチャートのように自動化することができる。
【０１０８】
図９に示すように、ユーザにより情報隠蔽対象のプログラムPが入力されるとともに変数vが指定されると（ステップ０、以下ステップを単にＳと記載する）、情報隠蔽装置１における生存範囲算出部２（図１参照）により手続き間生存性解析が行われ、変数vの生存範囲が算出される（Ｓ１）。その後、被覆メソッド算出部３（図１参照）により、生存範囲算出部２により算出された生存範囲に基づき、変数vの被覆メソッドm1,…,mkが求められる（Ｓ２）。
【０１０９】
そして、クラス抽出判定部４（図１参照）により、被覆メソッドm1,…,mkのうち１つでも変数vにアクセスしないか否かが判断されることで、新規クラスを抽出する必要があるか否かが判定される（Ｓ３）。すなわち、クラス抽出判定部４により、v∈def(n)∪use(n)なる頂点nを被覆メソッドm1,…,mkのいずれかが持つときYesと判定され、そうでないときNoと判定される。
【０１１０】
Ｓ３においてYesの判断がなされた場合、局所変数化実行部５（図１参照）により、変数vが被覆メソッドの局所変数とされ（Ｓ４）、情報隠蔽されたプログラムP'が出力される。具体的には、変数vが、被覆メソッドm1,…,mkの局所変数の位置に移動される。
【０１１１】
すなわち、vがVP'に属さないものとされ、VP'に属さない新しい変数v'1,…, v'kが、v'i∈localP'(mi)(1≦i≦k)の位置に追加される。さらに、プログラムPとプログラムP'とが等価になるように、プログラムPで出現する全ての変数vが、新たな変数v'1,…,v'kに置き換えられる。必要に応じて、各mi(1≦i≦k)とその呼び出し先メソッドとの間で、変数v'iの受け渡しも行われる。
【０１１２】
一方、Ｓ３においてNoの判断がなされた場合、クラス抽出実行部６（図１参照）により、（ａ）新規クラスを抽出する処理、（ｂ）変数vを新規クラスのメンバ変数の位置に移動する処理、および（ｃ）変数vにアクセスするメソッドを新規クラスに移動する処理が実行される（Ｓ６）。
【０１１３】
より具体的に説明すると、（ａ）新規クラスを抽出する処理では、ClassP':= ClassP∪{c}とされる。ただし、cはClassPには属さないものである。そして、（ｂ）変数vを新規クラスのメンバ変数の位置に移動する処理では、v∈memberP(c')であるc'について、vをmemberP'(c')に属さないものとし、なおかつv∈memberP'(c)とする。
【０１１４】
また、（ｃ）変数vに直接アクセスするメソッドを新規クラスに移動する処理では、当該メソッドをl1,…,ljとすると、メソッドl1,…,ljを可能な限りcに移動する。つまり、v∈def(ni)∪use(ni)なる頂点niを持つメソッドli(1≦i≦j)に対し、belongsP'(li):= cとする。移動できない場合、vにアクセスするメソッドをc内に作成(Encapsulate Field)し、vへのアクセスをそのメソッドの呼び出しに置き換える。
【０１１５】
Ｓ６における（ａ）〜（ｃ）の処理が終了したら、インスタンス配置部７（図１参照）により、新規クラスのインスタンスが被覆メソッドの局所変数とされる（Ｓ７）。具体的には、cのインスタンスo'1,…,o'kが、m1,…,mkの中でそれぞれ宣言される。ただしmiがフレームであるとき、o'iはメンバ変数として宣言される。そして、メソッドl1,…,ljの呼び出しが、o'1,…,o'kに対するメソッド呼び出しに置き換えられる。
【０１１６】
たとえばPのmi中で、lh()が呼び出されるとき、P'中ではその呼び出しが、o'i.lh()に置き換えられる。必要に応じて、各mi(1≦i≦k)とその呼び出し先メソッドとの間で、o'iの受け渡しが行われる。
【０１１７】
そして、情報隠蔽装置１は、Ｓ７の処理を完了した後に、情報隠蔽されたプログラムP'を出力する（Ｓ５）。
【０１１８】
上述した情報隠蔽リファクタリングの一連のフローにより、情報隠蔽が行われるまでの過程を、図１０（ａ）に示すプログラムが入力された場合を例にして説明する。図１０（ａ）に示すプログラムが情報隠蔽装置１に入力されると、上記Ｓ１およびＳ２を踏むことにより、被覆メソッドはf1として求められる。
【０１１９】
そして、Ｓ３の判断においては、被覆メソッドf1が変数vにアクセスしないと判断されるので、Ｓ６を踏むことにより、図１０（ｂ）に示すように、新規クラスとしてclassBが抽出され、変数vがclassBのメンバ変数の位置に移動される。また、変数vにアクセスするメソッドf2およびf３は、classBに移動される。さらに、Ｓ７を踏むことにより、図１０（ｂ）に示すように、classBのインスタンスbが、被覆メソッドf1の局所変数とされる。
【０１２０】
なお、本明細書では説明の便宜上、情報隠蔽の対象となる変数を１つとしたが、複数の変数を同時に隠蔽するようにしても構わない。
【０１２１】
〔３−２−２．アルゴリズムの計算量〕
以下では、プログラムの記述長を１、全メンバ変数の数をvとして、情報隠蔽アルゴリズムの時間計算量の解析を行う。
【０１２２】
先ず、生存性解析の時間計算量について検討する。非特許文献１より、KillおよびUseの時間計算量は、ともにO(l・v)である。同様に、Liveを計算するアルゴリズム（図８参照）の時間計算量も、明らかにO(l・v)となる。また、情報隠蔽アルゴリズムで解析の対象となる変数をただ１つとすると、生存性解析全体での時間計算量はO(l)となる。一方、被覆メソッドを求める計算もO(l)で実行可能であり、その他の部分もO(l)で実行可能である。
【０１２３】
これらの時間計算量に基づけば、以下の補題が得られる。
【０１２４】
（補題）プログラムの記述長に対し、情報隠蔽アルゴリズムは線形時間で動作する。
【０１２５】
〔３−３．半自動情報隠蔽リファクタリング〕
情報隠蔽リファクタリングをすべて手動で行うと、リファクタリング手順を保存することが極めて困難になることが予想される。そこで、以下ではプログラム変換の正確性が保証される範囲で、最大限ユーザの意図を反映できるような半自動情報隠蔽リファクタリングを構成する方法について説明する。
【０１２６】
まず、ソースコードの可読性を最も左右するのは、新規にクラスを構成するか否かの判定であると考えられる。よって、新規にクラスを構成するか否かを指定するフラグを、情報隠蔽装置１への入力データに加える。
【０１２７】
ここで、新規にクラスを構成しなければ情報隠蔽の効果が得られない場合や、逆に新規にクラスを構成しても情報隠蔽の効果が得られない場合は、その判定を機械的に行い結果をユーザに通知する。
【０１２８】
次に、変数vの局所変数化を行う場合、被覆メソッドのすべての呼び出し元が同一クラス内にあれば、被覆メソッドの代りにそれらのメソッド内で変数vを局所変数化してもリファクタリング手順は同様に保存されることから、移動先となりうるメソッドを列挙しユーザに選択させる。
【０１２９】
同様に、新規クラスを抽出する場合、指定した変数にアクセスしないメソッドを新規クラス内でカプセル化してもリファクタリングには影響しない。したがって、新規クラス構成時に付加的に移動するメソッドを指定できるよう、インタラクションを追加する。
【０１３０】
これらの考察に基づいたユーザ対話型の情報隠蔽アルゴリズムを、図１１に示す。
【０１３１】
まず、情報隠蔽装置１に、情報隠蔽対象のプログラムPが入力され、さらに変数vがユーザに指定された後（Ｓ１０）、生存範囲算出部２（図１参照）により手続き間依存性解析が行われ、変数vの生存範囲が算出される（Ｓ１１）。そして、被覆メソッド算出部３（図１参照）により、変数vの被覆メソッドm1,…,mkが求められる（Ｓ１２）。
【０１３２】
その後、クラス抽出判定部４（図１参照）により、新規クラスを抽出するか否かのフラグfがfalseか否かが判断される（Ｓ１３）。なお、フラグfは、情報隠蔽装置１への入力データとして含まれているものである。
【０１３３】
そして、フラグfがfalseのとき、以下のようにしてプログラムPを情報隠蔽したプログラムP'が構成される。すなわち、クラスc'をv∈memberP(c')とおくと、vの移動先メソッドの集合Mを、c'のメソッドの中からユーザに選択させる（Ｓ１４）。なお、移動先メソッドとは、被覆メソッドまたはその上位にあるメソッドを意味する。
【０１３４】
また、Ｓ１４における処理は、液晶ディスプレイ等の表示機器に表示されたクラスc'の中から、マウスやキーボード等の入力手段を介してユーザが集合Mを選択することで実現可能である。
【０１３５】
ただし、Mは、M=M1∪…∪Mkと表され、各Mi(1≦i≦k)は、miまたはその上位に位置する互いに上下関係を持たないメソッドからなる集合であるとする。もちろん、{m1,…,mk}もMの候補である。
【０１３６】
Ｓ１４の処理の後、局所変数化実行部５（図１参照）により、M中の各メソッドm∈Mの局所変数の位置に変数vが移動され（Ｓ１５）、情報隠蔽されたプログラムP'が出力される（Ｓ１６）。
【０１３７】
すなわち、局所変数化実行部５は、vをVP'に属さないものとし、VPに属さない新しい変数v'を、v'∈localP'(m)の位置に追加する。そして、PとP'とが等価になるように、m中において出現する全てのvをv'に置き換える。必要に応じて、各m∈Mと、その呼び出し先メソッドとの間で、v'の受け渡しを行う。
【０１３８】
また、Ｓ１３においてフラグfがfalseではないと判定されたら、以下のようにプログラムPを情報隠蔽したプログラムP'が構成される。
【０１３９】
先ず、Pにおいてvが所属するクラスをc'(すなわち、v∈memberP(c'))とおくと、新規クラスのインスタンスを宣言するメソッドの集合Mを、c'のメソッドの中からユーザに選択させる（Ｓ１７）。Ｓ１７における処理は、液晶ディスプレイ等の表示機器に表示されたクラスc'の中から、マウスやキーボード等の入力手段を介してユーザが集合Mを選択することで実現可能である。この際、ユーザに選択候補として提示するメソッドは、変数vに直接アクセスするメソッド以外を含めてもよい。
【０１４０】
ただし、Mは、M=M1∪…∪Mkと表され、各Mi(1≦i≦k)は、miがvに直接アクセスする（すなわちv∈def(n)∪use(n)なる頂点をもつ）場合、miまたはその上位に位置する互いに上下関係を持たないメソッドからなる集合であるとする。また、直接アクセスしない場合、各Mi(1≦i≦k)は、その集合または{mi}であるとする。
【０１４１】
Ｓ１７における処理の後、クラス抽出実行部６（図１参照）により、（ａ）新規クラスを抽出する処理、（ｂ）変数vを新規クラスのメンバ変数の位置に移動する処理、および（ｃ）変数vにアクセスするメソッド、およびＳ１７でユーザに指定されたメソッドを新規クラスに移動する処理が実行される（Ｓ１８）。
【０１４２】
より具体的に説明すると、（ａ）新規クラスを抽出する処理では、ClassP':= ClassP∪{c}とされる。ただし、cはClassPには属さないものである。そして、（ｂ）変数vを新規クラスのメンバ変数の位置に移動する処理では、v∈memberP(c')であるc'について、vをmemberP'(c')に属さないものとし、なおかつv∈memberP'(c)とする。
【０１４３】
そして、（ｃ）変数vにアクセスするメソッドおよびＳ１７でユーザに指定されたメソッドを新規クラスに移動する処理では、cに移動するc'中のメソッドl1,…,ljを、vに直接アクセスするメソッド、およびそれ以外のメソッドでＳ１７でユーザに指定されたものを、として設定する。
【０１４４】
Ｓ１８の処理が完了したら、インスタンス配置部７により、新規クラスのインスタンスが移動先メソッドの局所変数とされる（Ｓ１９）。
【０１４５】
すなわち、インスタンス配置部７は、cの各インスタンスo'をM中の各メソッドm∈Mの中でそれぞれ宣言(ただしmがフレームであるとき、o'はメンバ変数として宣言)し、m中でのl1,…,ljの呼び出しをo'に対するメソッド呼び出しに置き換える。たとえばPのm中で、lh()が呼び出されるとき、インスタンス配置部７は、P'中ではその呼び出しをo'.lh()に置き換える。また、インスタンス配置部７は、必要に応じて各m∈Mと、その呼び出し先メソッドとの間で、o'の受け渡しを行う。
【０１４６】
そして、情報隠蔽装置１は、Ｓ１９の処理を完了した後に、情報隠蔽されたプログラムP'を出力する（Ｓ１６）。
【０１４７】
〔４．情報隠蔽リファクタリングの応用〕
本実施形態の情報隠蔽リファクタリングは、クラス図をベースとしない新しい基本リファクタリングである。情報隠蔽リファクタリングと他のリファクタリングとを組み合わせることで、幅広い設計変更を扱うことが可能になる。また、本実施形態の情報隠蔽リファクタリングは、変数のスコープと生存期間との最小化を目的としているため、わずかな修正を加えるだけでクラスを持たない従来の手続き型言語に対しても適用可能になる。
【０１４８】
〔４−１．イテレータデザインパターンの自動生成〕
本実施形態の情報隠蔽リファクタリングによって、図７のプログラムを図５のプログラムに自動変換することができるが、図５のプログラム内で生成された新規クラス NewClass は, イテレータデザインパターン（非特許文献６参照）における Iterator クラスに他ならない。このように既存のソースコードへのイテレータデザインパターンの導入を、本実施形態の情報隠蔽リファクタリングの特別な適用例とみなすことができる。
【０１４９】
〔４−２．メソッド抽出との組み合わせ〕
本実施形態の情報隠蔽リファクタリングをメソッド抽出と組み合わせることで、純粋な手続きの中から新しいクラスを抽出, 分離することが可能になる。たとえば、図２（ａ）に示すプログラムPAのfunc2(), func3()をインライン化し、メンバ変数vを局所変数化して得られる以下のプログラムを考える。
【０１５０】
【数５】
2006201981.tif 000007
【０１５１】
ここから、以下の（１）〜（３）の手順を踏んで本実施形態のリファクタリングを適用することで、新しいクラスを構成することができる。
【０１５２】
（１）変数vをメンバ変数化する
（２）L1 および L2 をそれぞれ別メソッドとして抽出する(この時点でプログラムPAが得られる)
（３）本実施形態の情報隠蔽リファクタリングを適用する(図２（ｃ）参照)。
【０１５３】
同様の操作は、図７の open(), read(), close() をインライン化し、counter を局所変数化したプログラムに対しても適用できる。このことは、プログラム中の多くのクラスが、単純な手続きの中から抽出・分離離可能であることを示唆している。
【０１５４】
〔４−３．非オブジェクト指向言語への適用について〕
クラスをモジュールとみなし、メンバ変数をモジュール内に隠蔽された大域変数とみなすことで、本実施形態の情報隠蔽リファクタリングを非オブジェクト指向の手続き型言語にも適応することができる。この場合、図９に示すアルゴリズムを以下のように変更する必要がある。
【０１５５】
すなわち、Ｓ６における処理（ａ）を、P'中に新規モジュールcを追加する処理（ａ’）とし、Ｓ７における処理を省略する。これは、Ｓ６およびＳ７の処理全体を、クラス抽出処理に置き換えることに相当する。
【０１５６】
参考のため、非オブジェクト指向言語へ適用可能となるように、本実施形態の情報隠蔽装置１の構成を変更したものである情報隠蔽装置の構成を図１２に示す。図１２に示すように、非オブジェクト指向言語へ適用可能な情報隠蔽装置１’は、生存範囲算出部２と、被覆メソッド算出部３と、モジュール分離判定部（モジュール分離判定手段）４’と、局所変数化実行部５と、モジュール分離実行部（モジュール分離実行手段）６’とを備えている。すなわち、情報隠蔽装置１’は、情報隠蔽装置１におけるクラス抽出判定部４およびクラス抽出実行部６を、それぞれモジュール分離判定部４’およびモジュール分離実行部６’に置換し、インスタンス配置部７を省略した構成であるといえる。
【０１５７】
ここで、モジュール分離判定部４’は、クラス抽出判定部４と同様の処理を行うことにより、モジュール分離が必要か否かを判定するものである。また、モジュール分離実行部６’は、P'中に新規モジュールcを追加する処理を行うものであり、クラス抽出実行部６とほぼ同様の処理を行うものである。
【０１５８】
ただし、関連研究および〔３．情報隠蔽リファクタリング〕欄冒頭でも触れたように、モジュールはクラスとは違ってインスタンス化できず、さらにプログラムの全体に渡って生存するため、抽出した変数の生存期間は一般には最小化されない。
【０１５９】
〔５．今後の展望およびまとめ〕
本実施形態の情報隠蔽リファクタリングは、クラス図をベースとしない、新規な基本リファクタリングである。そして、本実施形態の情報隠蔽リファクタリングの最大の特徴は、変換に際して複数メソッドの内部情報を利用することであり、そのため本実施形態の情報隠蔽リファクタリングは手続き間生存性解析技術を用いている。
【０１６０】
また情報隠蔽は、概念上は単純なものであるにもかかわらず、本実施形態の情報隠蔽リファクタリングが示すように、ソースコードに対する操作手続きとして表現した場合は非常に複雑な形態をとりうる。これは、従来の手続き型オブジェクト指向言語の設計上の問題であると捉えることも可能である。したがって、本実施形態の情報隠蔽リファクタリングを自然に扱えるよう、従来の言語設計を改善する方向性も検討していけばよいと思われる。
【０１６１】
また、本実施形態の情報隠蔽リファクタリングの今後の課題としては、
（１）リファクタリングアルゴリズムを実装し実行時間などの評価を行う
（２）クラス間解析手法を用いてアルゴリズムの適用可能範囲を拡張する
（３）イテレータ以外のデザインパターンの生成への適用可能性を検討する
（４）プログラム中に存在する全クラス中のどの程度の割合を本手法を用いて構成可能であるか調査する
などを挙げることができる。
【０１６２】
〔６．補足〕
本実施形態の情報隠蔽装置１の各手段における処理手順は、ＣＰＵなどの演算手段が、ＲＯＭ（Read Only Memory）やＲＡＭなどの記憶手段に記憶されたプログラムを実行し、キーボードなどの入力手段、ディスプレイなどの出力手段、あるいは、インターフェース回路などの通信手段を制御することにより実現することができる。
【０１６３】
したがって、これらの手段を有するコンピュータが、上記プログラムを記録した記録媒体を読み取り、当該プログラムを実行するだけで、本実施形態の情報隠蔽装置１の各種処理を実現することができる。また、上記プログラムをリムーバブルな記録媒体に記録することにより、任意のコンピュータ上で上記の各種機能および各種処理を実現することができる。
【０１６４】
この記録媒体としては、マイクロコンピュータで処理を行うために図示しないメモリ、例えばＲＯＭのようなものがプログラムメディアであっても良いし、また、図示していないが外部記憶装置としてプログラム読み取り装置が設けられ、そこに記録媒体を挿入することにより読み取り可能なプログラムメディアであっても良い。
【０１６５】
また、何れの場合でも、格納されているプログラムは、マイクロプロセッサがアクセスして実行される構成であることが好ましい。さらに、プログラムを読み出し、読み出されたプログラムは、マイクロコンピュータのプログラム記憶エリアにダウンロードされて、そのプログラムが実行される方式であることが好ましい。なお、このダウンロード用のプログラムは予め本体装置に格納されているものとする。
【０１６６】
また、上記プログラムメディアとしては、本体と分離可能に構成される記録媒体であり、磁気テープやカセットテープ等のテープ系、フレキシブルディスクやハードディスク等の磁気ディスクやＣＤ／ＭＯ／ＭＤ／ＤＶＤ等のディスクのディスク系、ＩＣカード（メモリカードを含む）等のカード系、あるいはマスクＲＯＭ、ＥＰＲＯＭ（Erasable Programmable Read Only Memory）、ＥＥＰＲＯＭ（Electrically Erasable Programmable Read Only Memory）、フラッシュＲＯＭ等による半導体メモリを含めた固定的にプログラムを担持する記録媒体等がある。
【０１６７】
また、インターネットを含む通信ネットワークを接続可能なシステム構成であれば、通信ネットワークからプログラムをダウンロードするように流動的にプログラムを担持する記録媒体であることが好ましい。
【０１６８】
さらに、このように通信ネットワークからプログラムをダウンロードする場合には、そのダウンロード用のプログラムは予め本体装置に格納しておくか、あるいは別な記録媒体からインストールされるものであることが好ましい。
【産業上の利用可能性】
【０１６９】
本発明によれば、プログラムの設計変更作業におけるユーザ負担を軽減することができ、プログラムの開発効率を大幅に向上することが可能となる。よって、本発明は、プログラム開発を行う種々の産業へ利用可能である。
【図面の簡単な説明】
【０１７０】
【図１】本発明の情報隠蔽装置の一実施形態に係る構成を示すブロック図である。
【図２】図２（ａ）は、情報隠蔽対象のプログラムの例としてのプログラムPAを示す図であり、図２（ｂ）はPAに対してクラス抽出を適用した後のプログラムを示す図であり、図２（ｃ）はPAにおける変数vに本発明の情報隠蔽方法を適用した後のプログラムを示す図である。
【図３】本発明の情報隠蔽方法の概念を示す図である。
【図４】図４（ａ）は、情報隠蔽対象のプログラムの例としてのプログラムPBを示す図であり、図４（ｂ）は、PBにおける変数vに本発明の情報隠蔽方法を適用した後のプログラムを示す図である。
【図５】本発明の情報隠蔽方法により、新規クラスのインスタンスをソース上に複数個配置して情報隠蔽を行った後のプログラムを示す図である。
【図６】図２（ａ）のプログラムPAをCCFGで表現した図である。
【図７】情報隠蔽対象のプログラムの例を示す図である。
【図８】手続き間生存性解析に用いるLive(n)の計算アルゴリズムを示す図である。
【図９】本発明の情報隠蔽方法を示すフローチャートである。
【図１０】図１０（ａ）は、本発明の情報隠蔽方法における情報隠蔽対象のプログラムの一例を示すものであり、図１０（ｂ）は、図１０（ａ）のプログラムから新規クラスを抽出する概念を示す図である。
【図１１】本発明の情報隠蔽方法の他の構成例を示すフローチャートである。
【図１２】本発明の情報隠蔽装置の他の構成例を示すブロック図である。
【符号の説明】
【０１７１】
１    情報隠蔽装置
２    生存範囲算出部（生存範囲算出手段）
３    被覆メソッド算出部（被覆手続き算出手段）
４    クラス抽出判定部（クラス抽出判定手段）
５    局所変数化実行部（局所変数化実行手段）
６    クラス抽出実行部（クラス抽出実行手段）
７    インスタンス配置部（インスタンス配置手段）
４’  モジュール分離判定部（モジュール分離判定手段）
６’  モジュール分離実行部（モジュール分離実行手段）
【図１】
2006201981.tif 000008
【図２】
2006201981.tif 000009
【図３】
2006201981.tif 000010
【図４】
2006201981.tif 000011
【図５】
2006201981.tif 000012
【図６】
2006201981.tif 000013
【図７】
2006201981.tif 000014
【図８】
2006201981.tif 000015
【図９】
2006201981.tif 000016
【図１０】
2006201981.tif 000017
【図１１】
2006201981.tif 000018
【図１２】
2006201981.tif 000019