
以前、このteratailである質問の回答をしたら他の方にこのように言われました。
「ローカル変数が多いことが非常に気になります。ローカル変数はいわば『メモ』の働きをしますから、あまりに多いと本当に重要な情報が埋もれてしまうのです。
ローカル変数を減らすためには、メソッドチェーンやそれに準ずるもの(一時変数の積極的利用)、適切なサブルーチン化などが考えられます。
特にフラグを必要とする処理は、アーリーリターンを駆使すれば簡潔に書ける場合が多いです。
また、変数をスコープの頭でまとめて宣言するのも一般にはアンチパターンとして知られますので、避けておいた方が良いかと思います。」
javaでは変数をスコープの頭でまとめて宣言するのはなぜダメでしょうか?
これだと、コードを書くとき「この変数を使おう」と思ったときその行に変数を宣言することに
なるのですか?(つまり変数宣言とかつて宣言した変数の処理が混ざる)
C言語だと最初に変数を宣言するのですかJavaでは違うのでしょうか?
どなたがご教授お願い致します。
<追記>
Java
1int []data = {3,4,5}; 2int sum = 0; 3for(int i = 0; i < data.length; i++){ 4 sum += data[i]; 5} 6int average = sum / data.length;
Java
1int []data = {3,4,5}; 2int sum = 0; 3int average; 4for(int i = 0; i < data.length; i++){ 5 sum += data[i]; 6} 7average = sum / data.length;
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

2018/04/05 04:12

回答9件
0
アンチパターンといわれたがどうすればいいかわかりません
アンチパターンであっても動いているのであればまずはいいのです.
ただ、「アンチパターンである」もしくは「〜に見える」と指摘された際は, リファクタリングの時期に来ているとお考え下さい.
つまり、
ローカル変数が多いことが非常に気になります
は現在のコードにおけるブロック粒度がそれなりに大きく、処理内容をより細かいものに分解できるのではないか?という提案であり,
変数をスコープの頭でまとめて宣言するのも
も, スコープ全体が冗長に見えている査証です.
結局kaztoさんがおっしゃっているとおり「単一機能のコードが短くなれば自ずとローカル変数の数は少なくなるし、変数の定義場所についても気にならなくなる」が真相です.
投稿2018/04/05 00:37
総合スコア4756
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2018/04/05 00:40

0
ベストアンサー
javaでは変数をスコープの頭でまとめて宣言するのはなぜダメでしょうか?
上記の疑問に対する答えです。恐らく、下記の事を言っているのだと思います。
java
1public class Hoge { 2 public static void main(String[] args) { 3 int localCounter; 4 //ここではlocalCounterを一切使っていない処理が100行あったとする。 5 //・・・・・・・・・・・・・・・・・・・・ 6 //・・・・・・・・・・・・・・・・・・・・ 7 //・・・・・・・・・・・・・・・・・・・・ 8 //・・・・・・・・・・・・・・・・・・・・ 9 //処理終わり。 10 //ここで初めて何らかの演算をする。 11 localCounter = localCounter + 1; 12 13 return localCounter; 14 } 15}
とすると、上記のプログラムを初めて読んだ人がlocalCounter
を調査しようとした時、一切使っていない処理100行の中でもその変数が使われているかどうかを意識しなければいけません。(・・・・処理の中でもlocalCounter
が使えるので)
一方で、下記の様にすると
java
1public class Hoge { 2 public static void main(String[] args) { 3 //ここではlocalCounterを一切使っていない処理が100行あったとする。 4 //・・・・・・・・・・・・・・・・・・・・ 5 //・・・・・・・・・・・・・・・・・・・・ 6 //・・・・・・・・・・・・・・・・・・・・ 7 //・・・・・・・・・・・・・・・・・・・・ 8 //処理終わり。 9 //ここで初めて何らかの演算をする。 10 int localCounter; 11 localCounter = localCounter + 1; 12 13 return localCounter; 14 } 15}
localCounter
を宣言した後のみ意識すればよいので、プログラムを読むときに意識する行数を大幅に
減らすことが出来ます。この場合、中間の100行は何の意識もしなくて良いですね。
変数宣言とかつて宣言した変数の処理が混ざる
ここが上手く理解できなかったのですが、どの様なプログラムの書き方をイメージされての質問でしょうか?
もし、回答内容に齟齬があれば、質問への追記をお願いします。
投稿2018/04/05 00:21
編集2018/04/05 00:22総合スコア3027
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2018/04/05 00:50

退会済みユーザー
2018/04/05 01:09

0
結局、物事の善し悪しなんか、正当な理由があるかどうかです。
頭でまとめて宣言する理由って何でしょうか?
その理由が正当なものであるならば、全然問題ないと思いますし、
その理由が正当なものでなかったとしても、自分なりの理由があるということが重要です。
僕の場合は、頭でまとめて宣言するメリットは全くないと考えます。
maisumakunさんのコメントにある通り
かつてのC言語の制限やJavaScriptの巻き上げなどのような、特別な理由がJavaにはないので、
ローカル変数は使う時に宣言して、スコープはできるだけ小さくすべきだと思っています。
影響範囲を小さくしていきたいからです。
単純に読みにくい
変数が宣言されてから、その変数が使われるまでに何百行とあったりすると、
その変数の状態変化を気にしなければならない範囲が広すぎてうんざりします。
で、結局何も使われていないと分かるとドッと疲れます。
motuoさんの回答がとても分かりやすいです。
まだいらないのに宣言して、結局いらないまま終わる
ちょっといい例が思い浮かばなくて変なコードなんですが、例えば以下のような感じです。
単なるメモリーの無駄遣いです。
使う前に宣言と適切な初期化をすべきです。
Java
1public List<String> toList(String arg) { 2 List<String> tempList = new ArrayList<>(); 3 List<String> resultList = new ArrayList<>(); 4 Map<String, String> tempMap = new HashMap<>(); 5 if (arg == null) { 6 // tempList, resultList, tempMap が無駄になる 7 return null; 8 } 9 /* 10 * tempListにゴニョゴニョする 11 */ 12 if (tempList.isEmpty()) { 13 // resultList, tempMapが無駄になる 14 return null; 15 } 16 /* 17 * tempMapにゴニョゴニョする 18 */ 19 if (tempMap.containsKey("error")) { 20 // resultListが無駄になる 21 return null; 22 } 23 /* 24 * ようやくresultListを構築し始める 25 */ 26 return resultList; 27} 28
投稿2018/04/05 01:47
総合スコア4666
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
変数をスコープの頭でまとめて宣言するのも一般にはアンチパターンとして知られますので、避けておいた方が良いかと思います。
私はC言語で育った人間なので、このアンチパターンには懐疑的です。
ローカル変数を減らすためには、メソッドチェーンやそれに準ずるもの(一時変数の積極的利用)、適切なサブルーチン化などが考えられます。
が適切にできていれば、自然とローカルスコープの変数の数も減るだろう、と思っています。
投稿2018/04/05 00:16
総合スコア7196
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/04/05 00:28

退会済みユーザー
2018/04/05 00:40

0
javaの標準入力された値をその後の入力された値と比べて結果を返すプログラムがうまく作れません。
この質問の回答だと思いますが。
ソースコードを見て気になった点を列挙します。
main
メソッドに全部記述されているのでテストがしずらい。
メソッドの分割しすぎもよくありませんが、制御の流れが変わっている時点(入力、出力)で該当の処理を関数化したほうが読む人の負担が減ります。
0. flag
変数の命名と宣言場所が適切ではないかと、勝敗の判定を表すjudge
が適切ではないでしょうか。
0. dataとsampleの比較部分はforループで回すか、LouiS0616さんの回答の通り基数を掛け算して比較するという手も使えます。
見やすさと初学者さんへのわかりやすさもソースコードの一つの指標ですが、
個人的には**コードがテストしやすいかどうか(テスト容易性)**も重要なポイントではと個人的に思います。
2018/04/05追記
質問文の追記ソースコードは変数:average
と変数:sumをint
型で宣言しているため、data
が{1,2}
の時に算術平均が1となり正しく算出されません。
変数をdouble
型もしくはjava.math.BigDecimalクラスで宣言するか以下のコードでも可能です。
Java
1import java.util.stream.IntStream; 2 3public class A120426 { 4 public static void main(String[] args) { 5 int[] data = { 1, 2 }; 6 double average = IntStream.of(data).average().orElseThrow(null); 7 System.out.println(average); 8 } 9}
投稿2018/04/05 02:43
編集2018/04/05 04:11総合スコア5846
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
アンチパターンといわれたがどうすればいいかわかりません
まだまだ勉強中かと思いますので、それほど気にしなくてよいです。
多くのコードをみて勉強すれば、そのうち意識しなくても対処できます。
書籍だと、やはりリファクタリングが良いかと思います。
あと、webでおすすめは、間違ったコードは間違って見えるようにするは、いろいろためになると思います。
あなたが初心者プログラマか、あるいは初めて使う言語のコードを読もうとするとき、どの部分も同じように不可解に見える。そのプログラミング言語を理解するようになるまでは、簡単なシンタックスエラーにさえ気がつかない。
学習の最初のフェーズにおいて、私たちが「コーディングスタイル」と呼んでいるものを認識するようになる。
ハンガリアン記法についても、もしかしたら正しい使い方がわかるかもしれません。(すでに知ってるかもしれませんが)
ローカル変数が多いことが非常に気になります
こちらは、オブジェクト指向エクササイズが、オススメです。
コードを分割する時期になったら気にしてみては、どうでしょうか。
投稿2018/04/05 00:56
総合スコア4828
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2018/04/05 00:59

0
変数をスコープの頭でまとめて宣言するのも一般にはアンチパターンとして知られますので、
文字通りの意味であれば、「そんな事はないだろう」と思いますが、「ローカル変数のスコープに、ブロックスコープのある言語では、関数スコープだけでなく積極的にブロックを使って、ローカル変数のスコープを小さくしよう」ということなら、賛成です(限度はあると思いますが)。
また、該当プログラムでは、冒頭での宣言と同時に値の代入を行っていますね。プログラムの中身を読んでないのですが、「その代入は、そのタイミングが最適か?(プログラムを読む人の観点で)」という検討をされていないのであれば、検討すべきでしょう。
「代入タイミングを考慮した上で、初回代入時点で変数宣言すべき(宣言と初回代入を分けるべきでない)」という意図のコメントであれば、それはそれで有りだろうと思います。
投稿2018/04/05 00:39
編集2018/04/05 00:41総合スコア86295
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2018/04/05 00:45

0
C言語だと最初に変数を宣言するのですかJavaでは違うのでしょうか?
スコープの違いではないでしょうか。
C言語にはブロックスコープがありません。
コメントより指摘頂きました。
比較的新しいC言語の仕様では、ブロックスコープが存在するそうです。
変数の寿命は出来るだけ短くするのがベターです。
従いまして、C言語でもブロック毎に変数を宣言したほうが良いでしょう。
投稿2018/04/05 00:22
編集2018/04/05 03:38総合スコア514
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/04/05 00:31
2018/04/05 00:56
2018/04/05 02:13 編集
2018/04/05 02:25

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。