• ベストアンサー

長編プログラミングの設計のコツ

都合の良い話ですが、書籍や時間の取られる専門的な勉強を避け、 出来るだけ簡単にプログラムを設計するコツを知りたいのです。 今までは、どのような言語でも、数百行のコードを思いつくままに、 浮かんだアイデアを取り入れながら、コーディングして来ましたが うまく行っていました。 数ヶ月前に、1万行程度のコードを書いていて、 コードを見やすくするために、汎用処理を別ファイルにまとめたり、 関数化したり、オブジェクトにしたりして、20個以上のファイルに 分割されたコードが出来ました。 ブロック単位での挙動はテスト済みだったのですが、いざ完成直前に バグが頻発しました。 デバッグに入り、1連の処理が複数ファイルに分散されている事や 複数の関数から参照される処理が多々存在するなど、修正した部分 が新しいバグを引き起こすような事態になり。 コーディングよりもバグを取り除く事に遥かに時間が掛かり過ぎて、 結局、1からつくり直す事にしました。 前回の失敗を無くすため、なるべく各関数の依存度を下げ、カプセル化 やコメントをまめに書く事にに勤めました。 すると、今度はコードが3割程度長くなった挙句、1つのファイルの コードが長くなり、頓雑な、依存度を下げるために使った処理や変数の 数も倍以上に増えて、思いつくまま流れるようなコーディングが出来ず、 結局毎日作業開始時には、長々としたコメントを読むことから始めなく てはいけません。 一日3時間位しか取れない作業時間のうち、その作業に1時間は取られて はかどらず、挫折してます。 是非、主観的なご意見で構いませんので、お勧めの方法があれば アドバイス頂けませんでしょうか? ○参考にしてください。 デバッグの際に複数ファイルに渡った変数や処理の参照が作業を 困難にしているのは解っているが結局出来上がるとそうなってしまう か冗長なコードになってしまう。 記憶に頼る管理は極端に苦手(一日たつと、何を書いていたのか解らず、コード全体を読み直す事がしばしば)。 ファイル構造を始めに決めて処理の流れをある程度書き出して始めた たが、実際にコーディングを始めると思いつくままにコーディングが できす、構造管理に気を取られ頭が真っ白になる。 変数をハッシュなどでまとめて解りやすくしたつもりが、意外と読みにくい。 今までは、デバッグに関しては、記述ミスや、1つずつの変数や関数の 動作をトレースする事で事足りたので、今回も、それ以外のデバッグ 方法は取っていない。

質問者が選んだベストアンサー

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

私はプログラム全体の細かい構造などいちいち長いプログラムを書いているときは覚えていません。 なので、プログラミングするときは修正する箇所のコメントさえ見れば修正できるプログラム構造になっているのが望ましく、出来るだけそうなるように工夫しています。 1.変数を出来るだけ持ちまわらないほうが良いが、グローバル化したほうが単純化するなら、あえてそうする必要もある。 2.同じような処理は名前を統一する(名称でやる事が分かるように)。変数名も同様。 3.出来るだけ変数に対する操作を行う箇所を少なくする。同じような処理は関数化する。あちこちで修正するとバグの元。ただし無理やりひとつの関数にまとめるのもバグの元。 4.データは同じ関連の物をひとまとめにして構造化する。ばらばらにすると管理できません。 5.プログラム全体を階層化して管理する。 6.関数間のインターフェイスは出来るだけシンプルにする。 とりあえず、参考になるサイト http://www.rsch.tuis.ac.jp/~sekiguch/lecture/oyoron/2005/siryo/program_design.htm http://www.smg.co.jp/~toyo/Program/index17.html >ファイル構造を始めに決めて処理の流れをある程度書き出して始めた >たが、実際にコーディングを始めると思いつくままにコーディングが >できす、構造管理に気を取られ頭が真っ白になる。 これも疑問です。ファイル構造を管理するモジュールは1つにすべきでファイル構造をファイル入出力している場所ごとに管理するなど無駄と言うかバグの元です。 一部でも良いので、ソースを見せてもらえると的確なアドバイスが出来るかもしれません。ファイル構造に関する関数と、それを呼び出している所など。

akaginoyama
質問者

補足

自己診断ですが、 出来ている箇所1、2、4 出来ていない箇所3、5、6 3は、関数化の基準をもって無い。 5は、始めに考えた階層が変更になってしまう。  つまり、これも基準が無い+コーディング中の思いつきで  構造が変わる事が多々ある。 6は、僅か数行の関数に対して引数が6つなどと間抜けな  関数になってしまって、シンプルにと思い結局カプセル化  を断念して他の部分に依存してしまう事が多々。 そもそもトップダウンで物事をやったり考えた事が 無いので、それが一因かも・・・。 その他頂いた回答や情報に関しては、検討調査しています。 少し、時間が掛かりそうなのでまずは、この回答へのお礼を 申し上げます。

その他の回答 (2)

  • digh
  • ベストアンサー率61% (13/21)
回答No.3

よくわかります。 私も似たような状況で挫折中のプログラムがあります。 そしてやはり、扱うデータを整理して、分析して、 データ構造をまとめた後、そこからデータ構造を見返すばかりで 頭の中が整理できなくなっています。 そこで、私も No.2 の方の参考 URL の下段 (http://www.smg.co.jp/~toyo/Program/index17.html​) を一通り読んでみたのですが、どうも「ボトムアップ」による設計が苦手なんだとわかりました。質問者様も同じようなタイプではないでしょうか。 もしそうであるなら、私なりに考えた手法があるのですが、 参考までに如何でしょうか。私もこの後、以下の方法を試してみる予定です。 まず、データの量が多くて混乱しているので、一つのデータに絞って、それに関連する部分だけを作ってしまう。 一つのデータ(一つのファイル)を受け取り、なんらかの結果を返すプログラムを作ってしまうのです。プログラムの設計という観点から言えば、モジュール(機能単位)のプロトタイプ(試作品)を作る、といったところでしょうか。モジュール(機能単位)の単体テストを行うようなイメージにも近いかもしれません。 一つのデータをうまく処理できたら、次のデータも同様にして単独で処理をするようなプログラムを作り、そして、最終的にそれらを組み合わせてつなげる、という形です。 一つのデータごとにモジュールのプロトタイプ(試作品)を作って、正常な動作を確認したらそれを完成品(プロトタイプではなく、正規のモジュール)としてFixさせ、最後にそれらをつなげる。 私は、普段、プログラムを作るとき、機能毎に「分割」して関数などを作っていく手法(「アップダウン」)を用いていますが、その逆の手法(「ボトムアップ」)は経験が少ないです。そのため、「つなげる」という行為になれておらず、データ量が多いプログラムをデータ部分から設計した時にどうしても混乱してしまうのだと気づきました。 参考になりましたでしょうか。

akaginoyama
質問者

お礼

回答ありがとうございます。 >一つのデータをうまく処理できたら、次のデータも同様にして  単独で処理をするようなプログラムを作り最終的に  それらを組み合わせてつなげる まさにこれを、試していた最中でした。 一つ、面倒なのが、他の処理で得られた結果(加工済みのデータ) を中間処理データとして持つか、テストデータを作成するか と言う作業が増えてしまうことです。 さらっと書きましたが、結構骨が折れます。 正直申し上げますと、複数段階に別けての データ加工は精神衛生上少し苦痛ですw (不恰好なイメージが抜けません。) テストデータ作成はかなり困難なデータフォーマットです。 しかし、最終的に完成しないよりましですね。 愚痴ってすみません。 他の問題も出てくるかもしれませんが、今の所この方法が一番自身 のスキル的には実現できそうです。 No.2 様から頂いた情報も今理解に勤めているので共に参考に させていただきます。 思考錯誤中で直ぐには、結論がだせませんので、 まずはこの回答へのお礼をさせていただきました。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.1

言語は何ですか?又開発環境はどのようなものでしょうか? その辺のこともわかると、より良い回答が得られやすくなるかと思います。

akaginoyama
質問者

お礼

言語は、主にスクリプト言語系やPHPが多いですが悩みは同様です。 今回は、日本語プログラムなでしこで作成しています。 開発環境は付属エディタのみで、 プロジェクト・バージョン・フォルダ管理等はありません。 自身で階層フォルダをつくり管理する形態です。 特徴としては、 構造体、関数、オブジェクト指向ぽいグループ機能は使えます。 なでしこ選択の理由は、 ステップ数が他の言語の3分の1程度で済む。 ですが、どの言語を使っても同じ状況に陥入り挫折してしまうので、 出来るだけ、どの言語を使うかと言う以前の部分での アドバイスを希望しています。

関連するQ&A

  • case 文を解かり易く書くコツはありますか?

    アマチュアです。(C#利用中です) 1switch内に50程のcase~break文を並べています。 1 case~break内では5~12程の変数の値を設定しており、 最初は全部改行して書いていましたが、 仕様変更、追加、修正時に作業が大変かつミスが増えて来た為に 次は改行なしで1行に並べ半角スペースで整列させ その場は仕様変更、追加、修正時に作業は楽になりミスは減りましたが、 後でコードに問題があると解った時のデバッグや 変数に注釈が入れ難く解かり難くなり、余計面倒にもなりました。 次は外部に関数を作りそれを使ってcase毎に一括編集できる様にしましたが 数字の羅列だと修正時に余計なミスを起こす事が偶にあり、 文字列で送ってみるも後で有効な文字列の確認の手間が増えました。 また単語の文字列の羅列もミスが増えそうです。 今は引数が3~6程度に収まる様に複数の外部関数を作る様になりました。 でも外部の関数だと編集や確認の時が少し面倒だなとも感じてしまいます。 もっと解かり易く、編集し易く、ミスを起こし難い書き方って あるでしょうか? 自分はこういう時はこういう書き方や設計をしているとか、 そういうお話でも構いません。 お知恵を貸して頂けますと幸いです。

  • デバッグ情報が画面から流れないようにするには。

    膨大な量のデータを処理するプログラムを完成しました。私の環境は、ネット回線も細くパソコンも性能が低いこともあいまって、全ての処理を終えるのに2~3日かかるプログラムです。 それでも2~3日待てば処理が終わるのです。 やったー、と思ったまでは良いですけど、いざ動かしてみると、何やら警告が出ます。幸いまだデバッグ用の変数書き出しコードを削除していなかったので、だいたいバグが出たあたりが分かりました。処理結果を見てみると、確かに処理されたデータが壊れています。はて、何が原因かと、処理がその箇所を過ぎるあたりに注目しながらもう一度プログラムを動かしてみても、何故か今度は警告も出ないし、データを確認しても壊れていません。さっきのは一体なんだったのか。。。 とにかく再現できないことにはデバッグのしようもないので、プログラムの処理状況が分かりやすいように、変数の書き出しを削除せずに、あらためて今プログラムを動かしています。 プログラムを動かしてバグを再現するのは、デバッグの当然の手法でしょうが、変数を打ち出せば、なんせ2~3日かかるプログラムだけに、画面に大量の書き込みがなされて、警告が出ても流れてしまいます。そうかといって2~3日、ずっと画面を眺めているわけにもいきません。 変数をファイルに書き出すようにしても、警告はディスプレイに出ますから、するとどの時点で警告が出たのか、そのときの変数の値がどうだったのか、ファイルとディスプレイを時系列的に照らし合わせることが出来なければ、今ひとつ判断に困ります。 perl bugtuki.pl > test.txt のようにすれば警告もファイルに書き出すことが出来ますが、2~3日待たなければ、ファイルを開くことができません。 警告をファイルに書き出して、そのファイルをプログラムの処理中に見る方法などあるでしょうか。そのほか、この手の状況で、迅速にデバッグ情報を把握する方法がございましたらご教授ください。 一応DOS窓の画面バッファの高さを最大限にはしました。 言語はPerl 5.14.2。デバッグツールとしてActive Perl社のPerl Div Kit 8.2.1を使っています。

  • プログラミングテクニックについて(C言語).

    こんにちは.私は,大学でアプリケーションソフトをつくる作業を研究の一環としてやっています.C言語でコードを書いているのですが,計算処理の高速化を 実現したいと切に願っております. 例えば,以下のように2つの関数main とTest,があるとします. そのとき,Testは計算結果を返さないとします. #define MAX 100 void Test(i,j data); int main(void) { double data[MAX][3] for (i = 0; i <= MAX; i++ ){ for (j = 0; j <= MAX; j++){ // Test(i,j data); } } return 0; } この場合,毎回Test関数を呼ぶたびにdata配列を指すポインタを 渡し,さらにTest()関数内に定義されているローカル変数用のメモリ領域も 確保されます. ということは,処理を高速化するためには なるべくTest関数内の変数を できるだけへらせばいいのでしょうか? みなさんがプログラムを組むときに留意されているテクニックを 教えて頂きたいです. できればVC++ver6.0でのデバックツールをどのように つかってバグフィクスしておられるのかうかがいたいです. 以上、よろしく御願い致します.

  • Windowsプログラミング、全部これ覚えるのですか?(汗

    情報工学科に今年から配属された大学生です。 Cでプロンプト上で動いてくれるプログラムは多少出来てきたので この夏休みを利用してWindowsで動くGUIプログラムに挑戦しようかなぁ、 と思っています。そこで色々ネットで見回ってみたのですが。。。 http://web.kyoto-inet.or.jp/people/ysskondo/ こちらのサイトの解説などを多少読んでみたのですが・・・ この既に決められているかなりの量の変数や関数って全部覚えるのですか? ・・・正直恐れおののいている状況なのですが。 例えばウェブサイトを作ろうと思った場合、HTMLを直接コーディングするのもありですが 普通DreamweaverやGoLiveである程度自動でコーディングしてもらってから 所々自分でコードを手直しする、というのが一般的なやり方ですよね。 そういうことは出来ないのでしょうか? (別に特別楽を求めてるわけではないのです。全部覚えて全部手動でコーディングしなきゃいけないのならチマチマとやっていくつもりです。 ただもっと効率の良い方法があるのならそちらをとりたい、ということです。)

  • プログラミング中に壁にぶつかったら

    今、プログラミングを勉強しているのですが、 何かと壁に当たることも多いですが、 なんとか乗り越えて達成感を味わうことも多々あります。 最近は書籍のソースコードではなく、自分の頭で考えたような処理を記述できるようになってきました。 数日前から、ある処理について自分で発展させて、コードを書いていますが、一昨日あたりから、どうしてもわからなくなって、八方塞がりになってしまいました。自分でソースをすべてプリントアウトして眺めていても、混乱してきます。わかりそうで、見えてこないんです。だから素直に諦めきれないという状況です。 この丸二日間、悩みましたが結局いまだ理想の処理を実現するコードがかけていません。一部理想どおりにすると、一部に不具合が出るという状態です。 ほかにもやらなければならないことがあるので、 ひとまずその処理を実現させる作業は中断させて、 他のコードを組んだりしようと思っています。 そちらを勉強していくほうが今はためになるかと。 非常に名残惜しいですが・・! 場合にもよると思いますが、 どの程度悩んで分からなければ、 一度その処理に関しては、ストップされますか?

  • プログラミング言語の説明

    大学4年の者です.  プログラミング言語で作成したアプリケーションについての論文を作成しているのですが,プログラムの説明(変数や関数)についてはどのように説明を行えばよいでしょうか コメントを記載したソースコードを張り付ける方法も考えましたが,それだと文ではないだろうと考え辞めました. 関数の処理はかきつらねるべきなのか段落に番号を振ってわけるのかなど,同期にプログラミング言語を使った論文を書いている人がいないので困っています.

  • コーディングの綺麗な、サンプル。(長文

    コード、スクリプトの書き方で悩んでいます。 具体的には、 ユーザー関数内への、変数の渡し方です。 ・変数でユーザー関数に引き渡すか、 ・定数にして、読み出すか、 ・いっその事、グローバル変数にするか。 私は、よくミスをする人間と自覚しているので、 グローバル変数を使わない書き方にしているんですが。 (未定義のグローバル変数は、やはり危険だと思う。 けど、作成環境では未定義の変数は、意図的に Notice: Undefined variableの注意を出して、つぶす ようにしてるから、未定義はあり得ないし。^^;) 定数は便利なんですが、スクリプト中に$のない変数 があるのが違和感があるし、定数を使ってもそのまま 定数名が現れてしまう場合もあるので、$teisu = TEISU; としないといけないのが、かっこわるいかなー、と。 (明示的に定数を表示する方法もあるのかな?) 引き渡す方法も、ユーザー関数内から、ユーザー関数を 呼び出すと、引数のはしごになってしまうし、()内に 4、5個もあると、かっこわるいかなー、と。^^;;; まとめられる物は、まとめているんですが、。 (組み立て方も、悪いんだと思いますが。) この辺の臨機応変な使い方が、よく分からなくって。^^; 意見は分かれると思いますが、綺麗なコーディングって、 どんなものですか? 実際にPHPの掲示板等で、これは綺麗だよ。 または、綺麗なコーディングをするための、初心者に 毛が生えた程度の、わかりやすいHPもありましたら 教えてください。 私なりのかっこよさは、 グローバル変数は使わない。 ユーザー関数の引き渡しは、少ない。 未定義の変数は、使わない。 なんですが、探してもグローバルを多様しているものや 未定義の変数の注意がたくさん出るものばかりで。 それとも、私なりのかっこよさは、ずれているんでしょうか? 長くなりましたが、お願いします。

    • ベストアンサー
    • PHP
  • PHPのSQL文のデバッグ方法とコーディング方法について

    http://okwave.jp/qa3663217.html 上記のANo.2の回答についての疑問です 本来上記の回答者に対して便乗質問すればよかったのですが、 早々に締め切られてしまったので新しく質問させていただきます。 ☆上記のANo.2でSQLのデバッグ方法が回答されいる(下記に抜粋)のですが、 (1)は一般的なSQLデバッグ方法なのでしょうか? (2)は一般的なSQLの記述方法なのでしょうか? ●ANo.2の抜粋 (1)SQL文はヒアドキュメントをつかう (2)テーブルやフィールドはバッククォート、値はシングルクォートでくくる (3)変数は{$hoge}形式で参照する (4)SQL文の最後になるべく;はつけない (5)エラーはmysql_error()で確認する。 ●抜粋終わり ○私が疑問に思う理由は下記のとおりです。 (1)はHTML文を出力するには有効な機能だと思います しかし、SQLをデバッグする場合(特に動的SQLをデバッグする場合)、 最終的に加工されたSQL文をvar_dump,echo,print等で一切加工せずにデバッグしないと、 ヒアドキュメントへ加工中にSQLが(タイプミスとかカットアンドペーストミス)変わってしまう可能性があり、正しくデバッグできない可能性があると思います。 特にデバッグする人は、SQLをヒアドキュメントへ転記中に無意識のうちに正常なSQLに変換してしまっていて、バグの原因が掴めないなんてケースは結構見てきました。 デバッグする人は何がバグっているのかを探っているはずので、出来るだけデバッグ対象コードはまず生のまま見るべきだと思っています。 また、デバッグ終了後にデバッグ文を消す作業が発生し、 誤ってデバッグコード以外の必要なコードも削除してしまう恐れもあります。 var_dumpであれば、一括置換でコメントアウトしたり出来ますし、 あるいは、var_dumpをラップする関数を用意しておき、 デバッグフラグがONの場合のみvar_dumpを走らせるようにしておけば、 var_dumpを削除する作業そのものが不要で、 必要な時にデバッグON/OFF出来るかと思います。 (2)は「値はシングルクォート」(※1)は納得できるのですが、 「テーブルやフィールドはバッククォート」(※2)は、※1と混在してSQLを書いた場合、どれが列名でどれが変数(または定数)なのか、判別しにくくなり、 余計なバグを混入させたり、可読性を落としたりすると思います。

    • ベストアンサー
    • PHP
  • PHP4でMsgBox関数のようなものを作りたいが…

    PHP4で、VBなどのMsgBox関数を作りたいと思っています。 主にデバッグで変数の中身を表示させたりで用いたいのですが、 さらにMsgBoxの入力できるようにして変数に値を代入したりできるように できたらいいなと考えています。 何か参考になるURLやコードがありましたら、お教え下さいませ。 よろしくお願い致します。

    • ベストアンサー
    • PHP
  • phpのXSS対策 どこに問題が?

    phpのXSS対策について質問があります。 あるphpの参考書に以下のような記述があったのですが、理解できません。↓ ---------------------------------------------------------------------------------- ただし、htmlspecialchars()関数でのエスケープ処理は「&」「<」「>」「"」「'」を文字参照に変換するものなので、これらの文字をまったく使わずにJavaScriptのコードを記載できる場所に変数を表示させるようなHTMLを書いてしまった場合は対策できません。 たとえば、以下のような場所に変数を表示する場合です。このようなコーディングをしてしまった場合は、htmlspecialchars()関数でのエスケープ処理はXSSを防ぐことはできません。このような場所に変数を書かないように注意してください。 <a href="<?php echo $input; ?>"> ---------------------------------------------------------------------------------- この記述を書いてしまうとなぜhtmlspecialchars()関数では防げないのでしょうか? よろしくお願い致します。

    • ベストアンサー
    • PHP

専門家に質問してみよう