C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: プログラムを改善したいので厳しい目で指導してください。前半


(過去ログ 134 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■79265 / inTopicNo.1)  プログラムを改善したいので厳しい目で指導してください。前半
  
□投稿者/ javadb (1回)-(2016/03/18(Fri) 21:39:36)

分類:[.NET 全般] 

import java.util.Scanner;
import java.sql.*;

//メニュー
public class DB2 {
	public static void main(String[] args) {
		Scanner stdIn=new Scanner(System.in);
		System.out.println("メニュー");
		System.out.println("1:新規登録");
		System.out.println("2:個別検索");
		System.out.println("3:一覧表示");
		System.out.println("4:終了");
		try{						//半角数字以外で入力された時の対処
			System.out.print("メニューをお選びください:");
			int x=stdIn.nextInt();
			switch(x){
			case 1:
				torokuC.toroku();	//新規登録へ
				break;
			case 2:
				kobetuC.kobetu();	//個別表示へ
				break;
			case 3:
				listC.list();		//一覧表示へ
				break;
			case 4:
				endC.end();		//終了へ
				break;
			default:
				System.out.println("入力内容が間違っています。");
				System.out.println();
				main(null);
			}
		}catch(Exception e){
			System.out.println("入力内容が間違っています。");
			System.out.println();
			main(null);
		}
	}
}

//新規登録
class torokuC{
	public static void toroku(){
		Scanner stdIn=new Scanner(System.in);
		stdIn.useDelimiter("\\r\\n");		//Scannerで読み込む時、区切りを"空白"から"改行"へ変更
		gcheckC gc=new gcheckC();
		ycheckC yc=new ycheckC();
		//登録内容入力
		System.out.println();
		System.out.println("新規登録する内容を入力してください。");
		System.out.print("学番:");
		gc.ga=stdIn.next();
		System.out.print("氏名:");
		String na=stdIn.next();
		System.out.print("生年月日(YYYYMMDD):");
		yc.ymd=stdIn.next();
		//登録内容の確認
		System.out.println();
		System.out.println("登録内容の確認");
		System.out.println("学番:"+gc.ga);
		System.out.println("氏名:"+na);
		yc.yscheck();	//生年月日の確認表示
		while(true){
		System.out.print("登録内容に間違いはないですか(1:はい 2:いいえ):");
		int mt=stdIn.nextInt();
		switch(mt){
		case 1:
			//学番エラーチェック
			try{
				gc.gacheck();		//学番チェッククラスへ
				if(gc.h==1){
					throw new Exception();	//エラーへ
				}
				gc.gscheck();		//学番チェッククラスへ
				if(gc.h==1){
					throw new Exception();	//エラーへ
				}
				gc.gycheck();		//学番チェッククラスへ
				if(gc.h==1){
					throw new Exception();	//エラーへ
				}
			}catch(Exception e){
				System.out.print("入力しなおしますか(1:はい 2:いいえ):");
				int n=stdIn.nextInt();
				switch(n){
				case 1:
					toroku();				//新規登録へ
					break;
				case 2:
					DB2.main(null);			//メニューへ
					System.out.println();
					break;
				}
			}
			//生年月日エラーチェック
			if(yc.a==1){
				System.out.println("生年月日が正しく入力されていません。");
				System.out.print("入力しなおしますか(1:はい 2:いいえ):");
				int n=stdIn.nextInt();
				switch(n){
				case 1:
					toroku();			//新規登録へ
					break;
				case 2:
					DB2.main(null);		//メニューへ
					System.out.println();
					break;
				}
			}
			yc.yacheck();
			yc.ymcheck();				//生年月日チェッククラスへ
			if(yc.h==1){
				System.out.print("入力しなおしますか(1:はい 2:いいえ):");
				int n=stdIn.nextInt();
				switch(n){
				case 1:
					toroku();			//新規登録へ
					break;
				case 2:
					DB2.main(null);		//メニューへ
					System.out.println();
					break;
				}
			}
			int yyy=Integer.parseInt(yc.ymd);
			//↓mysql登録文
			Connection con=null;
			try{
				con=DriverManager.getConnection("jdbc:mysql://localhost:3306/javadb","workusr","workpass");	//ログイン
				Statement stm=con.createStatement();
				String sql="insert into gakusei values('"+gc.g+"','"+na+"','"+yyy+"')";	//SQL文	(登録
				int result=stm.executeUpdate(sql);
			}catch(Exception e){
			}finally{
				if(con!=null){
					try{
						con.close();
					}catch(SQLException e){
						System.out.println("MySQLのクローズに失敗しました。");
					}
				}
			}
			//↑
			if(gc.h<1){
				System.out.println("登録しました。");
				}
				System.out.println();
				System.out.print("お選びください(1:メニュー 2:終了):");
				int e=stdIn.nextInt();
				System.out.println();
				switch(e){
				case 1:
					DB2.main(null);
					break;
				case 2:
					endC.end();
					break;
				}
			break;
		case 2:
			toroku();
			System.out.println();
			break;
		default:
			System.out.println("入力が間違っています。");
			System.out.println();
			continue;
		}
		break;
		}
	}
}

//個別表示
class kobetuC{
	public static void kobetu(){
		Scanner stdIn=new Scanner(System.in);
		stdIn.useDelimiter("\\r\\n");
		gcheckC gc=new gcheckC();
		ks b=new ks();
		System.out.println();
		System.out.println("検索する学生番号を入力してください。");
		System.out.print("学番:");
		gc.ga=stdIn.next();
		gc.gacheck();
		gc.gscheck();
		gc.gncheck();
		Connection con=null;
		try{
			con=DriverManager.getConnection("jdbc:mysql://localhost:3306/javadb","workusr","workpass");	//ログイン
		Statement stm = con.createStatement();
        String sql = "select * from gakusei where gakuban='"+gc.g+"'";
        ResultSet rs = stm.executeQuery(sql);
        while(rs.next()){
            b.gakuban = rs.getInt("gakuban");
            b.name = rs.getString("name");
            b.birthday = rs.getString("birthday");
            System.out.println("検索結果 -> " + b.gakuban + ":" + b.name + ":" +b.birthday);
            System.out.println();
			System.out.print("お選びください(1:更新 2:削除3:メニュー4:終了):");
			int w=stdIn.nextInt();
			System.out.println();
			switch(w){
			case 1:
				b.kousin();
				break;
			case 2:
				b.sakuzyo();
				break;
			case 3:
				DB2.main(null);
				break;
			case 4:
				endC.end();
				break;
			}
        }
		}catch(Exception e){
			System.out.println("入力内容に間違いがあります。");
			System.out.print("入力しなおしますか(1:はい 2:いいえ):");
			int n=stdIn.nextInt();
			switch(n){
			case 1:
				kobetuC.kobetu();
				break;
			case 2:
				DB2.main(null);
				break;
			}
		}
	}
}

//一覧表示
class listC{
	public static void list(){
		System.out.println();
		Scanner stdIn=new Scanner(System.in);
		Connection con=null;
		try{
			con=DriverManager.getConnection("jdbc:mysql://localhost:3306/javadb","workusr","workpass");
			Statement stm=con.createStatement();
			String sql="select * from gakusei";
			ResultSet rs=stm.executeQuery(sql);
			while(rs.next()){
				int gakusei =rs.getInt("gakuban");
				String name =rs.getString("name");
				String birthday =rs.getString("birthday");
				System.out.println("学番:"+gakusei+"\t 名前:"+name+"\t 生年月日:"+birthday);
			}
		}catch(Exception e){
		}finally{
			if(con!=null){
				try{
					con.close();
				}catch(SQLException e){
					System.out.print("MYSQLのクローズに失敗しマスター");
				}
			}
		}
		//削除
		while(true){
		System.out.print("データを削除しますか(はい:1 いいえ:2):");
		int hoh=stdIn.nextInt();
		if(hoh==1){
			try{
				con=DriverManager.getConnection("jdbc:mysql://localhost:3306/javadb","workusr","workpass");
				Statement stm=con.createStatement();
				String sql="delete from gakusei";
				int num = stm.executeUpdate(sql);
				System.out.println("データを削除しました。");
			}catch(Exception e){
			}
		}else if(hoh==2){
			System.out.println();
			DB2.main(null);
			break;
		}else{
			System.out.println("入力が間違っています。");
			System.out.println();
		}
		}
		}
}

//終了
class endC{
	public static void end(){
		System.out.println("終了しました。");
	}
}

//学番チェック
class gcheckC{
	Scanner stdIn=new Scanner(System.in);
	int g;
	int h=0;
	String ga;
	void gacheck(){		//学番英数字チェック
		try{
			g=Integer.parseInt(ga);
		}catch(Exception e){
			System.out.println("英数字で入力してください。");
			h=1;
		}
	}
	void gscheck(){		//学番の桁チェック
		char[] gs=ga.toCharArray();
		if(5!=gs.length){
			System.out.println("学番が5桁ではありません。");
			h=1;
		}
	}
	void gycheck(){		//学番既存チェック
		Connection con=null;
		try{
			con=DriverManager.getConnection("jdbc:mysql://localhost:3306/javadb","workusr","workpass");	//ログイン
			Statement stm=con.createStatement();
			String sql="select * from gakusei where gakuban='"+g+"'";	//ffSQL文
			ResultSet rsa=stm.executeQuery(sql);
			while(rsa.next()){
				int gakub=rsa.getInt("gakuban");
				if(g==gakub){
					System.out.println("その学番は既に存在します。");
					h=1;
				}
			}
		}catch(Exception e){

引用返信 編集キー/
■79272 / inTopicNo.2)  Re[1]: プログラムを改善したいので厳しい目で指導してください。前半
□投稿者/ もりお (5回)-(2016/03/19(Sat) 02:13:20)
No79265 (javadb さん) に返信
力作ですね。私もちょっと眺めてみようかしら。
投稿はこのトピックにまとめてしまった方がいんじゃないでしょうか。

引用返信 編集キー/
■79274 / inTopicNo.3)  Re[2]: プログラムを改善したいので厳しい目で指導して
□投稿者/ daive (84回)-(2016/03/19(Sat) 09:28:30)
2016/03/19(Sat) 15:06:16 編集(投稿者)

後で参照しやすくするために、リンク書いておきます。

プログラム内容
http://bbs.wankuma.com/index.cgi?mode=al2&namber=79271
プログラムを改善したいので厳しい目で指導してください。前半
http://bbs.wankuma.com/index.cgi?mode=al2&namber=79265
厳しめでご指導してください 後半
http://bbs.wankuma.com/index.cgi?mode=al2&namber=79266

追記、teratailへの投稿リンク
https://teratail.com/users/ook#question

まぁ、こっちは見ないかもねぇ。
引用返信 編集キー/
■79277 / inTopicNo.4)  Re[3]: プログラムを改善したいので厳しい目で指導してください。前半
□投稿者/ WebSurfer (872回)-(2016/03/19(Sat) 09:49:01)
マルチポストのようですので、他のポスト先の URL を貼っておきます
http://qa.atmarkit.co.jp/q/9863
http://qa.atmarkit.co.jp/q/9862

質問者さんへ>
http://bbs.wankuma.com/index.cgi?mode=al2&namber=79266
http://bbs.wankuma.com/index.cgi?mode=al2&namber=79271
でも書きましたが、マルチポストは普通ここのようなコミュニティでは歓迎されません。
理由が分からなければ「マルチポスト」ググってヒットする記事を読んでください。
引用返信 編集キー/
■79280 / inTopicNo.5)  Re: プログラムを改善したいので厳しい目で指導し
□投稿者/ daive (85回)-(2016/03/19(Sat) 11:11:46)
2016/03/19(Sat) 11:36:44 編集(投稿者)
2016/03/19(Sat) 11:34:35 編集(投稿者)、表現変更、誤字訂正

ざっと、コードを拝見してみました。
1.CUIで作っているにしても、
  内容が、あまりにも、会話型バッチ処理、DOS−BASIC的
2.機能が不足しているようです、
  要求仕様等を再検討した方が良いと思います。
3.このプログラムは、これで良いと思いますが、
  ユーザーインタフェースと、ロジック、DB操作部分、IO部分、など、
  意識して切り分けた方が改修が楽になります。
  今回の物では、規模が小さいので、練習にもなります。
  ⇒ユーザーインタフェースと、ロジック、各処理が分離していれば、
   ロジックを再利用して、GUI化も楽になる。
   各所にログを追加での場合も、分離が上手くいっていれば、楽ができます。
   分離単位毎や、処理毎に、単体デバッグが可能な様に作成すると、
   自動テストへの道が開けます。
  文字列定数、数値の定数を、生でハードコーディングして多用していますが、
  可能な限り、名称で使用します。リソース化したり、テーブル化したり、DB化したり。
  ⇒数値の儘では、時間が経ったとき、ロジックとして分離した時に意味が掴みづらくなる。
   文字列定数では、差替え、変更で、該当コードを弄る事になる。
   各クラス、処理の大づかみの部分に、処理の目的、内容、改訂履歴がありません。
   各クラス名が、意味のある名称になっていません。
   (個人的には、余り長い名称は嫌いですが、意味ある名称になっていないと、
    ’今日の自分は、明日は赤の他人’ですので、忘れた時に。。。)
  ⇒DB2?を使っているようなので、メッセージをDB2へ持たせてしまって
   フィールド(カラム)を複数持たせておいて、多言語対応可能としてしまったり。
  ロジックの検討不足、サボリコードがありませんか?。
   ymcheck(){ //生年月日の日付チェック
  など
  ⇒単純に、ユーザーインタフェースと、ロジックの分離を行っただけでも、
   スッキリとしたコードになる事も多いです。
   スッキリとした、判り易いコードは、デバッグ、修正、改修も
   しやすいです。

以下余談、雑談

コンピュータ用のプログラムって、
自分で使って、なんぼ。
人(他人)に使ってもらって、なんぼ。
自己満足や、自分用コードでは、現状でも良いのでは?
コードだけ書いて御仕舞ではないので、
コード書きだけでなく、文書類の作成も。

仕様書⇒詳細仕様書⇒コード作成用の各種書き物
  詳細仕様と平行して⇒テスト用のデータ準備、テスト項目の洗い出し
             場合により、できるだけ、根性悪、意地悪なデータを用意する。
           ⇒検査要領書の準備、確認
           ⇒機器使用の場合は、機器の設定や、設定確認要領、テストコード
コード作成用の各種書き物例:今回は簡単な内容なので、端折ってもよいかも。
クラス図、インタフェース表、状態遷移図、真理値表、他、必要に応じたもの
コードを書いて、自動作成可能な物もありますので、自動作成されない物を準備

>データ管理としても実用性がありクオリティが高い完璧なプログラムを完成を目指いています。。
>プログラムの構成としてはオブジェクト指向でトランザクション処理ではコミット(コミット自動処理)やロールバック等も考慮したいです。
>画面としてはボタン等などの機能を取り入れ、機能性、便利性、使用性のある画面も考えています
>機能としては検索機能、時刻機能、セキュリティ機能(パスワード)、記録機能、自動化ツール(テスト)機能等など必要最低限の機能は取り入れたいです。
>テストとしては自動ツールや重複チェックやエラーメッセージや例外処理やエラーや制御処理などには徹底的に力を入れたいです。
>データ管理、データの操作、機能性、便利性、使用性、セキュリティ等と重要視し問題点が一切なく正常に継続して作動をするプログラム制作を完璧に完成するために、>あらゆる面からかなり厳しくご指摘、ご指導等の方を宜しくお願いします。
ちゃちゃいれすると、すでに、完璧にはならない兆候が、、、
1.コード書きとは異なった、見た目雑務的な内容(仕様書書き他)が、あって、
  その上での、仕様を実現していれば、不具合があっても、使いにくくても、
  仕様の実現という事は、可能かもしれない。
2.想定する完璧とは、何でしょう?から定義しないと、
  永遠に完成しない傑作になるかも。
3.文脈的には、コンピュータのプログラムコードとプログラムの機能であるにしても、
  他者にそれを求める書き方は、既に完璧ではないのでは?
4.完璧は望んでも、得られない。限定された範囲では、それを満たす事は可能です。
5.少なくとも、想定環境、想定使用者、各所の目標レスポンス時間、各所の想定処理時間、
  イレギュラー処理の内容、ログの残し方他や、自動テスト書き、テストデータの準備、
6.あるべき姿、そうあって欲しい機能などの、
  目的、目標、仕様書作成、詳細仕様作成、テスト項目、検査要領書の作成やら、を
  目に見えるように、文書化する事。人は、忘れる生き物です。
7.コンピュータプログラムは、コードを書いて御仕舞ではない事、
  プログラム内容:http://bbs.wankuma.com/index.cgi?mode=al2&namber=79271
  で、仕様を示したつもりであれば、(掲示板用に端折ったのでしょうから)、
  雑談レベルでは、うんうん、いいねぇ、頑張って(^^♪
引用返信 編集キー/
■79282 / inTopicNo.6)  Re[5]: Re: プログラムを改善したいので厳しい目で指導し
□投稿者/ daive (86回)-(2016/03/19(Sat) 12:58:53)
>分類:[.NET 全般] 
となっていますが、JAVAのようですし、
使用を想定している環境が不明ですが、

現状のCUIについて、
一様対話型インタフェースと、なっていますが、
バッチ処理や、スクリプト処理を念頭において、
わざと、画面が流れていってしまう実装にしているのでしょうか?
そうでないならば、少なくとも画面モードは、
2種類あった方が良いです。
1.バッチ処理、スクリプト処理で使いやすい、現状型
2.ホームポジションがあり、画面が流れず、
  画面表示が書き変わる、古に良くあった形、
  GUIになる前の、ATMなんかで、ありましたけど、若いと知らないかも。
  この場合は、スクリーンサイズを、文字数で、想定します。
  良くやっていたのが、
  横80文字、縦20〜25行、ファンクション行1行ないし2行
 (これ様の、スクリーンレイアウト用紙なんてものも、ありましたねぇ)
  ’
  01行名:タイトル、バージョン、処理中他各種補助情報

  02行名:表示内容1行名、データや処理を表示
    :    :
  xx行目:表示内容XX行目、データや処理を表示

  最終行−2行目:コマンドライン、オプション表示、補助情報表示
  最終行−1行目:ファンクションキー表示1行目
  最終行目   :ファンクションキー表示2行目

  過去の有名処のエスケープコードや、Windows用の、DOS時代のエスケープコード表他は、ネットで探せます。
  対象がターミナルソフトか、LINUXのソフトターミナルか、Windows コマンドプロンプトか、
  文字コード考慮も必要になります。

データベースが、IBMのDB2を使っている場合は、情報が得られる場所は限られると思います。

引用返信 編集キー/
■79292 / inTopicNo.7)  Re[1]: プログラムを改善したいので厳しい目で指導してください。前半
□投稿者/ しま (106回)-(2016/03/19(Sat) 20:34:51)
No79265 (javadb さん) に返信

あなたの使っている java のバージョンを示して下さい

DB2.main() から DB2.main() を呼出していますが、これはどういう意図でそうしていますか?
意図して、故意にスタックを深くするのは何故なんでしょうか????
これだといつまで経っても(プログラムが終了するまで) new したクラスのインスタンスが解放できないのではありませんか?

DriverManager.getConnection() があちらこちらに散らばっていますが、これもどうなんでしょう。

しかも、listC.list() では DB2.main() を呼出しますから、 listC.list() の finally にいつ制御が移って
connection con や statement stm やの後始末が出来るのでしょうか?
そして、listC.list() では DriverManager.getConnection() を2度使っていますが、2度 getConnection() して con を取得
するのは何故ですか?
直前に取得した con の値を削除の処理でも使えばいいのではありませんか?

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -