De-Refactoring or Are Designs navigatable?

タイトルの意図は「リファクタリングの逆 or デザインはnavigatable?」


リファクタリングの一般的な定義(何も参照しながら書いてないので正確ではないけど)は「プログラムの振る舞いを保ったまま、設計(コード、プログラム)を改善する」という感じ。


じゃあ、逆に:あえて設計を改悪することは可能か? あるいは、設計は、悪い方向にいったりきたりすることは可能か?


そもそも、なぜ設計を改悪する必要があるのか? 何が動機か? 恐らく、一般的なプログラマには関係の無いテーマ。関係はあるのは、新しいプログラミング言語の機構とかコンセプトとかを提案しようとしている人とか、あるいは、設計に関わる新しい手法(最近だとDIとか)を提案、あるいは、評価しようとしている人。


研究の分野 or 論文では、新しい設計技術(言語とか)を提案して、その評価を行う際に、既存のコードを対象として、その新しい技術を用いることによって改善(リファクタリング)するケースが多い。例をあげるなら、AspectJ によるリファクタリングなど。


一般的にいえば、デザインパターンがその実装に用いる言語によって影響を受けるように、リファクタリングもどんな技術を用いるのかによって影響を受ける。


少し話はとんで、新しい技術が使えるようになると、今まで経験してきた設計の勘に影響を与える。たとえば、DI (Dependency Injection) に慣れた人は、DI が存在しなかった前は、どんな設計を行っていたのだろう?


あるいは、新しい技術を使っての設計は、チャレンジとなる。「チャレンジ」ってのは、その技術が有効 or 効果的 だろう ということを感じていたとしても、実際に適用してみるまではその新しい技術を使っての設計を行う選択肢を選択したことが正解だったとは、分からないということ。

たとえばAspectJを使ってのプログラミングや設計はどのようにすればいいのだろう。AspectJ的なプログラムの設計を選んで正しかったと自信を持つには、それなりの経験が必要だと思う。実際、僕はAspectJを使って2年ほどまあまあ大きなプログラム(2,3万行。コメント含む)を書いているけど、いまだにAspectJ的な設計が正しかった、という確証はない。


この確証を得にくい理由としては、設計が正しかったかどうかの判断の重要な基準のひとつが設計の進化性 or 適応性にあるからだと思う。つまり、AspectJ的な設計を選択したとして、その後のソフトウェアの進化、つまり、機能追加などのフェーズにうまく適応できるかどうかを通って初めて、選択肢が正しかったかどうかについての確証と自信に結びつくからだと思う。


そして、話を戻して、よほど暇な人でないと、設計の選択肢の比較なんてことは行わないと思う。たとえば、AspectJ的な設計を選択したとして、わざわざ「もし、AspectJを使えなかったとしたら(たとえば普通にJava)どんな設計を行っていただろう。そして、その後のソフトウェアの進化に、各選択肢(JavaAspectJ)はどのように異なって適応していっただろう。JavaAspectJでは、どのような異なる 設計の進化パスをたどることになったのだろう。」とかを実際に問いかけて、評価・検証してみる人はいないと思う。


にも関わらず、この問いかけは重要だと思う。


と書いてみたけど、全然まとまってないのでまた今後書き直すことにする。