ふにふにぷろぐらみんぐ(もっちり)

プログラマー?いいえ、技術オタクです。

メソッドの書きかたのメソッド

 スッキリわかるJava入門 第2版で、独学をしているめいなです。こんにちは!
 毎週1章、土曜の23:59までに終える!と自分で目標を立てているんですが、第5章の章末まで一度もサボらずにこれましたー。えへへ

 でも、書けば書くほどどうすればいいのか頭がこんがらがってくるので、はてなちゃん(ブログ記事編集画面)に話しながら考えてみたいと思いまーす
 数ヶ月後、あるいは数年後に読み返したときにツッコミができるようになってますよーに!


 今回の5章はメソッドについての章だったんだけど、基礎から応用まで一気に駆け抜けていて、「本当にこの書き方で理解できるの?正しく動くの?負荷はどうなの?」と思えるソースコードがよく出てきたし、ぼくの頭では完全には追いきれなかった…。
 1章30ページ程度という制約を設けていて、その中になんとか収めたんだろうな、という感じ。

 あとは自分で補完するしかない!と思ってはいたけど、章末問題を解いてみたら、ことごとく解答例と違うコードを錬成してしまった(笑)
 他にも「これって運用するにはどっちの方が便利なの?」とか「他のプログラマにとって読みやすい(間違いにくい)のはどっち?」とか「ぼくのコードの何がいけないの?(解答例として取り扱われなかった理由)」とか、まーいろいろ気になったので書き残しておきます。
 博識なIT系はてなー様方の忌憚なきご意見もいただけたら嬉しいです。それではいってみよう!

問題内容:メソッド「email」を定義し、以下の形式で画面に表示する
戻り値の型:なし
引数リスト:タイトル、アドレス、本文の3つ
処理内容:「アドレス」にメールを送信しました
     件名:「タイトル」
     本文:「本文」
以上3行を、それぞれの引数を使用して出力する

 はじめに書いたコードがこれ。

public class Main {
 public static void main(String[] args) {
  email();
 }
 public static void email() {
  String title = "メールのタイトル";
  String address = "メールの宛先アドレス";
  String text = "メールの本文";
  System.out.println("「" + address + "」に、以下のメールを送信しました");
  System.out.println("件名:「" + title + "」");
  System.out.println("本文:「" + text + "」");
 }
}

 引数リストはメソッドの後ろの()内に記述するというのを完全に忘れていて(ぼくには難しすぎた)、メソッドの中身で変数を宣言しまくって、出力内容まですべてメソッドまかせにしているコード。
 これでもちゃんと動くんですよね…引数リストを渡さなくても。
 ぼく的にはこういうコードが一番分かりやすくて好きです。


 続きましてー、解答例を見て「そういえば、引数リストはメソッドの後ろに書くんだった!!そうだった!」と叫んで、書き直したコードがこれ。

public class Main {
 public static void main(String[] args) {
  email("メールのタイトル", "メールの宛先アドレス", "メールの本文");
 }
 public static void email(String title, String address, String text) {
  System.out.println("「" + address + "」に、以下のメールを送信しました");
  System.out.println("件名:「" + title + "」");
  System.out.println("本文:「" + text + "」");
 }
}

 いちおう、教本に乗っていた「複数の引数を渡す例」の部分を参考に書いたものです。というか成分的にはわりとそそのままです。
 変数の後ろの()内に直接データをぶち込むやつ。ぶち込む個数と受け取り側の個数、またその順番が必ず正しくなければならないという制約が怖い。
 めちゃくちゃ長いコードを書くとき、対応箇所を探すだけで一苦労になりそうなのに大丈夫なのかな?というのがぼくの所感です。


 ここまで書いてて思ったことがあるので聞いてください。
 ぼくは今まで「[email]だけがメソッド名で、それを呼び出せれば引数リストとかどーでもいーじゃん…と思っていたけど、実際には引数まで含めて初めて本当のメソッド名になるのでは?
 「email」だけだと複数のケースの想定ができなくて不便だから、メソッドの中身を引数として()内に記述し、名前の一部としているのでは?
 この考えが正しいとすれば、mainでemail();だけを呼び出すプログラムはやっぱり不親切な設計ということになるよねー。


 それでもデータをぶち込むのはやっぱり抵抗があるな…と思いながらチェックした解答内容がこちら。

public class Main {
 public static void main(String[] args) {
  String title = "メールのタイトル";
  String address = "メールの宛先アドレス";
  String text = "メールの本文";
  email(title, address, text);
 }
 public static void email(String title, String address, String text) {
  System.out.println("「" + address + "」に、以下のメールを送信しました");
  System.out.println("件名:「" + title + "」");
  System.out.println("本文:「" + text + "」");
 }
}

 mainの中で変数を宣言するんかい!
 確かにmain中でうっかりした事故は起こりにくそうだけど、その代償に使える変数がどんどん減っていく気がする…。
 メソッドは他のメソッドに対してスコープの影響をかけずにあれこれできて、そのわりにメソッド名を呼び出すだけで実行が実現できる!という便利機能のはずなのに、なんとなく本末転倒なような。
 でも、メソッドに引数を指定してしまうとmainメソッドにも引数を指定する必要があって、そのためにはmainメソッド内で変数を宣言しなくちゃいけないので、これも仕方がなさそう。

 でも、個人的に引数リストは極力使いたくない(笑)
 メソッドAの中に複数の値を宣言しておいて、メソッドAを取り出すときに指定した値だけとりだしてくれる感じだと神!だと思う。
 メソッドAに入ってる変数と値の一覧が参照できるコマンドとかあればなおいいなー。リファレンスすれば変数名を間違うこともないし。


 なんとなーく、じわじわーと、Javaちゃんの意思の強さが露見してきたような気がする。
 Javaちゃん、おしとやかで万能なクラス委員長タイプかと思ってたけど、意外にも芯の部分はしっかりしていて簡単には意見を曲げなそう。笑
 Javaちゃん完全攻略に向けて頑張ろー。


 えー、続きまして追加問題です

問題内容:先ほどのコードにメソッド「email」をオーバーロードしてmainメソッドから呼び出す
戻り値の型:なし
引数リスト:アドレス、本文
処理内容:「アドレス」にメールを送信しました
     件名:無題(※引数を使用しない)
     本文:「本文」
以上3行を、それぞれの引数を使用して出力する

 「こんなの、オーバーロードなんかしなくてもさっきのmailメソッドを書き換えたらええやん!」とドヤ顔していたぼく(アホなので)。
 引数の数が違うから、オーバーロードしてできないことはないけど…
 やっぱり、オーバーロードも極力使いたくない(笑)
 ここまでブログを書きながらいろいろ考えてきたけど、1つのメソッドに対して複数のケースを持たせたいなら、いっそのことメソッド名を変えた方が安心できる…気がする。
 emailメソッドを親として、そこにすべての要素を書き込んでおいて実際に使用するのはemailの子メソッドとか。
 今回の問題だったら、

public class Main {
 public static void main(String[] args) {
  email101();
 }
/* public static void email() {
  String title = "メールのタイトル";
  String address = "メールの宛先アドレス";
  String text = "メールの本文";
  System.out.println("「" + address + "」に、以下のメールを送信しました");
  System.out.println("件名:「" + title + "」");
  System.out.println("本文:「" + text + "」");
 }*/
 public static void email101() {
  String address = "メールの宛先アドレス";
  String text = "メールの本文";
  System.out.println("「" + address + "」に、以下のメールを送信しました");
  System.out.println("件名:無題");
  System.out.println("本文:「" + text + "」");
 }
}

 こんな感じかな。
 親メソッド(email)は資料用で、メソッドとしては使用してません。
 まあ邪魔な情報になってしまうけど、いろいろと正しいかどうかを精査する必要のある引数ぶち込みよりはいいんじゃないかな…。
 コードの邪魔になるようなら別ファイルにメソッドリファレンス(人間用)を作って参照しながら進めたらいいかも。
 子メソッドの命名法としては、2進数でやれば単純明解で良さそう。
 親メソッドで宣言してる変数が5つなら0が5つから出発して、実際に使用する変数がある場所を1に書き換える感じで。
 こんな独自ルールでやってたら会社に入ってから大変なことになりそうだけど…笑


 本当はもう1題、章末問題 of 章末問題があるんだけど、解答例のコードがよく分からない(笑)し、頭が疲れた(笑)し、たぶんめちゃくちゃ長くなる…のでまた今度にしまーす。
 こんなぼくが書いたコードでもちゃんと意図通りに動かせたので、プログラミングって奥深いなーと思います。
 ラクをするための努力は惜しまない、なかなかアレな姿勢でこれからも頑張るぞぃ。

      • -

はてなブログについて:

 ソース埋め込み術を、しかもシンタックスハイライトつきのやつを会得しました!やったー!
 といってもめちゃ簡単ですよね。さすがはてなブログ
 でもその機能を使うためにまさか「はてな記法モード」にしなきゃいけないとか思いもよりませんでした(笑)
 確かに普通の人には不要な機能だもんなあ。
 URLを埋め込むのもできるようになったし、なんとなくおしゃれなブログっぽくなってて、すげえ!と言うより他ないです。
 めいなは はてなーマスターに 一歩近づいた!▼