見出し画像

AIはOOPの単一責任の原則を理解できている。逆に試されたのは自分だった😱

今日も懲りずにObject-Oriented Programming (OOP) の学習日記。そこから見えてきた「人とAIとがデザインパターンを介して」協業プログラミングするためには実は人の側の知識不足が深刻になるかもしれない、という話です。

まだOOPもデザインパターンも学習中なので、初心者レベルの感想です。あくまでも個人の感想です。ご注意下さい。

今日は第5章のSingletonのチョコレート工場を学習中。だがその途中でJavaコードをC# コードにChatGPTに変換させたときに気が付いたChatGPTの賢さ。もしかしたらAIはOOPの単一責任の原則(Single responsibility principle, SRP)を理解できているかもしれない😱いや、ほぼ間違いなく理解できていると思う。そう思った日記。

(約 5,800文字の記事です。)



たまたま自力変換コードとChatGPTコードを見比べていた

Singletonパターンの参考コードは短かったので今回は初めて自力でJava to  C# に変換してみた。コンパイルエラーは消えたが、もしかしたら何か忘れているかもしれないと思い、いつも通りChatGPTでコードをC# に変換させた。そして両者を見比べていて気が付いた。

ChatGPTコードの中に、オリジナルにはないメソッドが1つ追加されていた。おや?ナンダコレは?そして驚いた。

教科書のオリジナルコード

これはJavaだがこの部分についてはC# と何も違いはない。

public static ChocolateBoiler getInstance() {
	if (uniqueInstance == null) {
		System.out.println("Creating unique instance of Chocolate Boiler");
		uniqueInstance = new ChocolateBoiler();
	}
	System.out.println("Returning instance of Chocolate Boiler");
	return uniqueInstance;
}

インスタンスが既にあればその参照を返し、なければnew演算子でインスタンス化するというシンプルな内容だ。特に何にも問題はないように思われた。

ChatGPTの変換結果

そして次がChatGPTの変換結果。

ただし=>演算子を使うようにすることと、シンプルなIF文は三項演算子を使うように指示しています。なのでそこはスルーして下さい😅

オリジナルコードにはなかった「CreateUniqueInstance()」メソッドが登場している?ナンダコレ?と思ってよく読んでみると!

public static ChocolateBoiler GetInstance() =>
    _uniqueInstance == null ? CreateUniqueInstance() : _uniqueInstance;

private static ChocolateBoiler CreateUniqueInstance()
{
    Console.WriteLine("Creating unique instance of Chocolate Boiler");
    _uniqueInstance = new ChocolateBoiler();
    Console.WriteLine("Returning instance of Chocolate Boiler");
    return _uniqueInstance;
}

ChatGPTが新たに生成したCreateUniqueInstance()メソッド(OOP非学習者にとってはシンプルに「CreateUniqueInstance()関数」だと思ってOK)、この部分が「new演算子を使って新たにインスタンス化する仕事」の責任を負っているわけ。

ChatGPTが自発的にGetInstance()から「新たにインスタンス化する仕事」をCreateUniqueInstance()に分離したのだ。

OOP学習者にはピンと来たと思うが、これ、まさに単一責任の原則(Single responsibility principle)をChatGPTが見事に実演して見せたわけ!

オリジナルのコードでは、getInstance()メソッドに2つの機能が入っていたのだ。①インスタンスの有無の判定、②インスタンスがない場合にはインスタンス化する、という2つ。OOPでは1つのメソッドは1つの仕事しか担当させないという原則がある。

まぁ、今回の場合、分離してもしなくてもあまり問題はないのだが、ChatGPTはそこをあっさりと原則に従って分離したコードを出力してきたわけだ。

OOPのSRPの原則に従って分離したコードは、当然バグの混入リスクが減る上に、可読性が上がる。どの関数がどんな責任を負ってデータ処理をしているかが一発で分かる。

public static ChocolateBoiler GetInstance() =>
    _uniqueInstance == null ? CreateUniqueInstance() : _uniqueInstance;

上はシンプルに「インスタンスの有無を判定しているだけ」だとすぐに分かる。そしてもしインスタンス化されていなければCreateUniqueInstance()を呼び出している。責任の委任だ。

private static ChocolateBoiler CreateUniqueInstance()
{
    Console.WriteLine("Creating unique instance of Chocolate Boiler");
    _uniqueInstance = new ChocolateBoiler();
    Console.WriteLine("Returning instance of Chocolate Boiler");
    return _uniqueInstance;
}

上はメソッド名の通り、そのまんま「新規でインスタンス化する際のnew の処理を全部引き受けている。Console.WriteLineはコンソールに文字列を表示させる命令。最後にインスタンスを返す。

ここで元に戻ってオリジナルのJavaコードをもう一度見てみよう。

public static ChocolateBoiler getInstance() {
	if (uniqueInstance == null) {
		System.out.println("Creating unique instance of Chocolate Boiler");
		uniqueInstance = new ChocolateBoiler();
	}
	System.out.println("Returning instance of Chocolate Boiler");
	return uniqueInstance;
}

見比べてみればこちらの方が危険だとすぐ分かる。2つの機能が1つのメソッドにあるだけで、こんなにも見通しが悪くなるとは!

……と思ったら、ChatGPTのコードだと「"Returning instance of Chocolate Boiler"」という文字列が返される場合と返されない場合がある。インスタンスを返すという機能には問題ないが、コンソールに表示されるデバッグ用のメッセージでは、このメソッドの2度目以降の呼び出しでは沈黙する。ちょっと惜しい。三項演算子への書き換え指示の実行・非実行を上手く制御できていなかったようだ(無理に三項演算子に変換せずに素直に元のIFブロック表現のままでよかったわけだ)。

つ★ま★り、ChatGPTよ、余計なことをしてくれるな!💢とも言える。なのでまだまだAIは油断ならない😭



ChatGPTの実力を垣間見た(よい点も悪い点も)。そして色々考えることがある。


AIがOOPを考えると「とんでもない新たなデザインパターン」が生まれるのでは?🤔

OOPのデザインパターンは先人達の経験を再利用するという概念だ。だがAIがなかった頃の経験の集合体だ。

だが今後、AIがコーディングをすれば、もしかしたら、これまで手作業だった「人の限界」をAIがとんでもない斜め上の発想で、人類が出会っていない便利なデザインパターンを生み出してくれるのではないか?と、ふと思った。

人が思いつかないデザインパターンならば、人の編み出した従来通りのデザインパターンに含まれるはずがない。だがAIがOOPの原理を理解して組み合わせるならば、斜め上の発想で人が思いつきようもないデザインパターンを生み出す可能性がある。でも前述のようにしれっと穴が空いていたりする罠もある。

例えば新薬開発などでAIが駆使されているように、奇抜な組み合わせや発想はAIの得意分野。でもジャンジャンバンバン新薬が出ていないあたり、やはり穴は多そうね。

というかもうOOPデザインパターンの指示に従ってくれるのでは?

というかもしかしたら、AIにユーザーストーリーズというシナリオを説明し、設計指針として特定のデザインパターンを使うように指示し、将来的な応用の可能性の部分を伝えておき、完成コードの他にコードの解説を説明させるように指示したとすれば、どうなる?

AIが「AAAメソッドをBBBするために、Factory Methodパターンを使用しました。これによりCCC, DDDメソッドなどを将来的に自由に拡張できます。」などという解説と共にソースコードが出てきたとしたら?

そうなるとOOPという概念は「先人の経験の再利用」だけではなくなる。むしろOOPはAIとの協業プログラミングのための「共通言語」として機能することになる。これはとても重要なことだ。OOPが過去の経験の再利用だけではなくて、さらにAIとの共通言語にもなる可能性がある。ソースコードの作成指示だけ出なくて修正指示についてもOOPの概念で指示できるようになるので、AIとの協業の質が上がるのではないだろうか?


AIとの協業コーディングが可能ならば、常にプログラマ側の知恵不足のリスク

もしAIがOOPを理解しているならば、むしろ私、人間側のOOPへの理解不足や経験不足すら有り得る。多分今の私の知識よりもChatGPTのOOP理解の方が遥かに上だと思う。

AIの進化速度は人のそれを遥かに凌駕している。これは間違いない。今この瞬間ですら、地球上のあらゆる言語でChatGPTは人とチャットしているし、色んなプログラミング言語で他のプログラマと協業中なことだろう。

なので実は、足りないのは常にプログラマ側の知識や経験だったりするかもしれない。逆転現象が起こる?というか起こっている?(あえてOOPを使って表現すれば、依存関係反転の原則、Dependency Inversion Prinsiple

依存関係反転が起こる、というか起こっているのでは?

人がヘルパーとしてAIを使うのだが、そのアウトプットの質を高めるためにはプログラマ側がさらに勉強をしてAIと同じレベルで会話(チャット)できるように、つまり「その知識レベルに到達する」まで勉強を強いられる、という逆転現象。

設計原則
抽象に依存する。具象クラスに依存してはいけない。

この設計原則に沿って説明するとすれば、OOPとデザインパターンという抽象的な概念に人とAIが依存することで、コード設計レベルで両者が会話できることになる。

具象クラスに依存してはいけないという部分は、今AIと会話している具体的なソースコードに依存して会話してはいけない、という解釈になる。コードの実装部分についての会話になると、コード設計レベルかかけ離れていくし、その限定的なソフトウェア内で問題ないならば、何の問題にもならない。コード全体の設計レベルでプログラマがAIと会話するならば、そういう具体的なソースコードで話をするのではなくて、抽象、つまりデザインパターンレベルで会話すべき、という考えが見えてくる。

だが、ときどき出てくるAIの罠にも気を付けなければならない。全面信頼にはほど遠い。


だからデザインパターンを学んでいる。

そう、なので私がChatGPTにデザインパターンを使ってOOPでコードを書かせようとすれば、まず足りないのは私の側の知識不足という話😭

AIを使って高度な成果物を得るためには、その成果物を理解できるだけの高度な能力を「人が有する」必要がある。そうでないと成果物の正しさ・間違いを見抜けない。

結局、AIを使う側の能力がAI出力レベルの上限になるという話。AIを駆使しても自分がスーパーサイヤ人やスパイダーマンやアイアンマンになれるわけじゃない。成果物の質はあくまでも今の自分の能力で打ち止めになる。それ以外は「フェイク」であって、メンテもチェックも何もできない。つまりフェイク、偽物な成果物ってわけだね。

いつの日か私がデザインパターンを使ってChatGPTにソースコードを書かせられるようになりたい。その方がワクワクする😍

だからデザインパターンを勉強しています。ここまで書いてデザインパターンの学習のモチベーションが一気に上がった気がする。やったね🎉


今回の創作活動は約1時間45分(累積 約3,925時間)
(1,167回目のnote更新)

筆者はAmazonアソシエイト・プログラムに参加しています。(AmazonアソシエイトとはAmazon.co.jpの商品を宣伝し所定の条件を満たすことで紹介料をAmazon様から頂けるという大変ありがたい仕組みのこと。)
以下のリンクを経由してAmazonでお買物をするとその購入額の1~3%ほどのお小遣いが私に寄付されます。誰が何を買ったという情報は私には通知されませんのでご安心下さい😊 以下のリンクを経由して頂ければ紹介商品以外のご購入でもOKですよ~。


読んでくれてありがとう。気長にマイペースに書いてます。この出会いに感謝😊