プロが教えるわが家の防犯対策術!

私は、プログラミングを始めて1年目なのですが、
現在 PHP・JAVA・VBS・VB 等を主に使用しております。
最近は1000行以下の小規模の物から、やや規模の
大きなプログラミングにチャレンジしておりますが、
各言語でよくある自作関数機能などについて、質問したいのですが?

●抱えている問題点
お決まりの、処理や繰り返しの処理を関数化すると
言うのは大体解かってきたのですが。
インクルードファイルのダブリや細分化のレベルについて
中々うまく設計出来ないあげく、関数に値を渡すため無駄
な処理を増やしてしまう事が多々在ります。

●先輩方ベテランの皆様への自作関数に対する質問
1、開発の規模によって関数化の基準を設けているのでしょうか?
2、関数化による特有のディメリットは、在りますか?
3、その他、関数化についてのアドバイスがあればいただけませんか?

A 回答 (2件)

回答1:


・開発規模によっての関数化する基準はありません。
 その代わりに下の基準で『関数化』しています。
・(1)同じ処理を複数の箇所で使う場合→関数定義、マクロ関数、インライン関数などで記述
・(2)似た処理は引数の受け渡しで対応するため関数化させる
・(3)1つの処理に1つの関数を基準にすることで『部品化』できる→オブジェクト指向?
・(4)複雑な処理は(3)の『部品化』を元にデータ処理をするとスッキリ出来るので関数化
・(5)ソースファイルを見やすくするために関数化(1関数は最大でも50行まで)
 50行とは、普段使っているエディタの1画面が50行だからです。昔の MS-DOS 時代では
 22行ルールなどと呼ばれていました。→DOS 画面が25行なのでタイトルバーやメニューと
 ファンクションキーを除いた22行です。これが22行ルールって事だ!これに則って50行。

回答2:
・仮引数への複写や、関数を呼び出すためのオーバーヘッド(処理ルーチンに移動させる)に
 時間がかかってしまうこと。でも、今は CPU 速度をあまり気にしない時代ですが…。
 この場合は、マクロ関数やインライン関数、またはアセンブラで処理を記述させれば高速に
 なります。アセンブラの前にマクロ関数やインライン関数を私は普段利用しています。
・処理をあまり関数に分けてしまうと管理が大変になること。
 このため、あるまとまった処理(関連した処理)を1つのファイル内にまとめて関数化します。
 処理内容、引数と戻り値などは必ずコメントします。→将来の自分のためにも記述。

回答3:
・小規模なものでも似たような(同じような)処理は沢山あります。
 ちょっとだけ引数や値が違うだけでいろいろなプログラムに組み込める処理は、テーマごとに
 関数化して自作ライブラリにします。このとき、拡張しやすく定義することです。
 拡張しやすいとは C++ や Java などでお馴染みの『オブジェクト指向』を取り入れます。
・データの処理(アルゴリズム)と
 入出力の処理(ファイル、画面描画など)は別々に管理します。ハードウェアに依存する部分と
 ソフトウェア的の部分を上手にやり取りできる仕組みが一番、拡張しやすい方法だと思います。
・引数が多い場合は構造体などを利用します。また、API 関数などや Java などの言語で用意されている
 関数の引数と戻り値を参考にして『自作関数』を作るお手本にします。
・引数が多い場合でも、よく変化する値は関数の引数にして、残りのパラメータは構造体でまとめて
 渡すようにすれば、無駄な処理は減らせると思います。
・インクルードファイルのダブリは C/C++ 言語では『#define』を上手く利用すれば2重インクルードを防止できます。
 下に C/C++ 言語ですが2重インクルードを防止する方法を載せます。→ソースのヘッダ部に記述すればよい。

サンプル:
#if !defined( _MAIN_HEAD_ )
# define _MAIN_HEAD_
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include <math.h>
#endif /* 2重 include 防止対策 */

最後に:
・会社などで自作ライブラリを使った場合。そのライブラリががないとプログラムをコンパイル
 できなくなる。自作ライブラリを一緒に配布するなどの必要があります。簡易マニュアル付きで。
・なお、会社などで指定された共通のライブラリがあった場合は、出来る限りそのライブラリを
 使います。また、そのライブラリを元に新しい処理(関数)を作成します。このときに、それ専用の
 ライブラリを作成します。→会社の為に『書き下ろす』わけだ。
・以上。参考に!
    • good
    • 0
この回答へのお礼

~~~~有難うございます!!~~~~
>処理内容、引数と戻り値などは必ずコメントします。
 コメント一つ取っても試行錯誤していたので助かります。

●関数は奥が深いですね~、それにしても、解説が解かりやすく
 具体的で初心者級の私にも良く解かり、「関数は使える」と再認識
 させられました。

●それにしても、専業のプログラマーさんは何割くらいの関数を別の
 プロジェクトに再利用されるのでしょうか?
 もしかして、関数貼り付けて殆ど終わりみたいな仕事もあるのかな~?

お礼日時:2007/04/13 08:16

回答1


開発規模によって関数化の基準を設けるというのは聞いたことがありません。
私の関数化の基準は、どうすればもっとも再利用性が上がるかを、常に念頭に置いています。
なぜならば、プログラム作成にかかるコストはほとんどが人件費であり、最もコストがかかる部分だからです。
最初に作るプログラムを徹底的に再利用可能にしておけば(再利用できる関数の割合を増やしておけば、あるいは、汎用的なライブラリを作成しておけば)、このプログラムにかかるコストは、
予算に対して120%になってしまうかもしれませんが、
次から作るプログラムの再利用率が50%とか多いときで90%以上になり、大幅なコストダウンが見込めるからです。

では、関数化するときの着眼点ですが、
関数の「強度」を最も強く、
関数の「結合度」最も弱くするように作ったほうが後で再利用しやすいです。(詳細は基本情報処理等のテキストを見ると良いでしょう)
「強度」がもっとも強い場合とは、その関数がたった一つの機能のみを実装している場合になります。(例:echo関数は文字列を出力する機能のみを有するため、強度が強いと言える)
「結合度」がもっとも弱いとは、その関数が他の関数に一切依存しない場合(マルチスレッドプログラムで呼び出しタイミングが有る場合も結合度が弱いことになるのかな)になります。(例:fwriteはfopenを先に呼んでいないと使えないので結合度が比較的強いと言える)
しかし、C等の構造化プログラミングでは上記のことを比較的徹底することが出来ますが、
java等のオブジェクト指向プログラミングでは、徹底することができないことが結構あります。
なぜならば、class内のメソッド(関数)は、class内変数やstatic変数を通して処理を行うことが多いので、メソッド間の「強度」、「結合度」が弱く(あるいは強く)なってしまうからです。
classの場合は、class自体を構造化プログラミングでの関数と同等と考えて、class自体の強度を強く、結合度を弱く出来るよう作ったほうがいいと思います。

回答2
デメリットの件ですが、やはり関数を呼び出すときのオーバーヘッドになります。特に組込みプログラミングで使用する、遅いCPU(16Mhzとか)の場合は、あえてインラインコーディングすることが多々あります。
また、関数の数が膨大になってくるので、個々の関数のバージョン管理や、関数名不足に陥ったりします。
また、共有ライブラリ内の関数に致命的な欠陥があった場合、それを利用しているプログラム全てに多大な影響を及ぼします。

回答3
関数名はperfixや、postfixを付けてして、関数名を見るだけで、
どのカテゴリの関数なのか、どんな機能なのかが一発でわかるようにしたほうがいいでしょう。
そうしないと、せっかく共通関数を作っても、第三者がプログラミングするときに、必要な関数を探すことに苦労してしまいます。
幸いにも必要な関数が発見できれば良いですが、
無いと判断したプログラマは、同じような関数を新たに作成してしまい、後で2重管理を迫られることになります。
共通関数等は機能一覧を作成して見やすくしておくと良いでしょう。
    • good
    • 0
この回答へのお礼

~~~~有難うございます!!~~~~
●具体的な数字や開発の現場でしか解からない事など、
 非常に参考になりました。

>次から作るプログラムの再利用率が50%とか多いときで90%以上
 大変な数字で、驚きました。
 おかげで貴重な時間を無駄にせずに済みそうです。

>class自体の強度を強く、結合度を弱く
 もっと、早く知っていればと思いました。
 
 

お礼日時:2007/04/13 11:09

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!