質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

10回答

5917閲覧

再利用性が高いクラスの作り方が分からない

dem0nmichik0

総合スコア37

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

3クリップ

投稿2018/12/19 23:58

実現したい事

これまで,基本三構造の構造化言語でコーディングしていたプログラムを「再利用性を高くする」ためにオブジェクト指向(クラス)を使ったプログラムに書き換えようとしています。

困っている事

下記,参考テキストを購読した結果,「グローバル変数がインスタンス変数候補になる」,「サブルーチン(関数)がメソッド候補になる」と書かれていました。なので,全ソース(.cpp)のグローバル変数と関数をまとめました。そこから,再利用性が高いクラスをどうやって作ったらよいのかが分からない状態です。クラス図やシーケンス図を作成したほうがよいのでしょうか?クラスの作り方やクラス設計の注意点を教えていただけると助かります。また,参考図書もありましたら,教えていただけると助かります。

【参考テキスト】
オブジェクト指向でなぜつくるのか 知っておきたいOOP,設計,関数型言語の基礎知識  平澤 章著

アプリケーション構成

3つのプロセス(.exe)があり,1つのメインプロセスの中で6個の画面フォームがある。
0. メインプロセス(Main.exe)

  • A画面
  • B画面
  • C画面
  • D画面
  • E画面
  • F画面
  1. 受信プロセス(Client.exe)
  2. 送信プロセス(Server.exe)

開発環境

OS:Windows7 32bit
IDE:Borland C++ Builder6

aaaaaaaa👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2018/12/20 00:00

C++での回答を求めているのであればCとC#のタグは外されては? 言語関係ないのであれば特化したタグと開発環境はなくても良いように思います。
guest

回答10

0

何画面もあってクライアントサーバーに分かれているものを初心者が全部クラス図からきっちり書いて作り上げるのは無理だと思います。

クラスを小さくすればするほど再利用性は高くなります。
つまり大きなアプリを作る時には膨大な数のクラスを作ることになります。

まずは知っている方法で動く物を作り、ほんのわずかな部分を切り取って汎用的なクラスに置き換え、それを繰り返してリファクタリングするのが一番現実的かと思います。

もし知っている方法で作ることもできないのなら、今作ろうとしているものは大きすぎます。もう少し小さなものから始めてください。

投稿2018/12/20 01:35

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こんにちは。

クラスは、要するにデータと関数をひとまとめにしたものです。
別の表現をすると、C言語の構造体に関数を付け加えたものです。
C言語でプログラムを書く場合、特定の構造体へのポインタを引数にとり、その内容をアクセスして処理するような関数を書くことが比較的頻繁にないでしょうか?(キレイに設計されたプログラムではよく見る構造です。linuxのカーネルとか)
ざっくり、その構造体へのポインタを引数とする関数を当該構造体(=クラス)のメンバ関数としたものが、クラスです。(内部構造的にもそのように実装されています。)

そのような特定の構造体をclassとし、その構造体へのポインタを引数としていた関数を、そのclassのメンバ関数として設計することが始めると良いように思います。これだけでも再利用性が格段に上がります。

なお、オブジェクト指向には他にも非常に強力な機能が多数ありますが、まずは最も基本であるデータと関数のセットとして切り出すことから始めると入りやすいと思います。

投稿2018/12/20 02:49

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

基本三構造の構造化言語でコーディングしていたプログラムを「再利用性を高くする」ためにオブジェクト指向(クラス)を使ったプログラムに書き換えようとしています。

そもそも、必ずしも**「再利用性を高くする」=「オブジェクト指向(クラス)を使う」**ではありません。

オブジェクト指向で再利用というなら、基底クラスが該当すると思います。
抽象化しても必ずしも継承する場面は無かったということもありますし、関数化して再利用なら、classでなくとも良い訳で。

なので、質問は「オブジェクト指向での共通化設計のポイント」って事なのかなと。
再利用を高くするというのに該当するのは基底クラスと共通関数(場合によってはインターフェースも)ですから、洗い出しの為には先ず、クラス設計を行う必要があります。
その為にはシーケンス図作ったりクラス図作ったりが必要で、都合の良い裏技は存在しないと考えた方が良いと思います。

投稿2018/12/20 05:18

編集2018/12/20 05:26
sazi

総合スコア25184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

momon-ga

2018/12/20 06:52

> 質問は「オブジェクト指向での共通化設計のポイント」って事なのかな そんな感じですね。再利用して拡張するっていう話よりも、共通化して 保守性をあげたいっていう観点であれば、とりあえず共通処理をライブラリ化して ユーティリティクラスつくればよさそうですね。
guest

0

クラスの作り方やクラス設計の注意点

…に関連あるような,無いような,
ものすごーく曖昧 且つ しょぼい話を書きますが…

例えばあなたがある処理を「関数」として書くとき,そこには「関数にする理由,利点,etc...」があるハズ.
その処理をその場にダイレクトに書かずに関数化するのはなぜなのか?

「クラス」も同様で,ある処理とデータの集まりをクラスとして書かんとする際には,
やはり「クラスにする理由,利点,etc...」があるハズ(あって然るべき.とりえあず"class"って書きたいとかじゃなく).
その中には「再利用性」に繋がる要素もあるハズ.
そんな感じのことを考えてみてはいかがでしょうか.

投稿2018/12/20 02:23

編集2018/12/20 02:24
fana

総合スコア11656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

momon-ga

2018/12/20 02:56 編集

曖昧というか、抽象(本質)ですね。 もとの質問が再利用するのが目的で、そのやり方を聞いてるような感じがあり、 そもそもの部分が抜けてる感じがしてました。
fana

2018/12/20 03:10

> 全ソース(.cpp)のグローバル変数と関数をまとめました これが出発点の状況であれば, 全てをどこか1箇所にまとめるのではなく「再利用{できる,したい}要素の単位毎に分けてまとめなさい」 みたいな話が「回答」になるのかもしれません.
momon-ga

2018/12/20 03:28

ですね。ただ「再利用したい要素の単位って、どうやって決めるの?」ってなり、結局「クラスにする理由,利点,etc...」っていう話に行き着くとは思います。
dem0nmichik0

2018/12/20 04:00

momon-ga様,fana様,回答ありがとうございます。 自分自身,関数にする方針はコーディングするときに何か所も使うコードを関数にしてコールしています。そして,メインプロセスの全画面(A~F画面)の関数をまとめた結果,3,4個は同じ関数がある状態です。同じ関数ではありますが,各画面毎にコンポーネントが違うので,同じ処理もあれば,異なる処理もある状態です。このような場合,その同じ関数名の同じ処理をメソッドにすればいいのでしょうか?事なる処理はクラスを継承して,画面特有の処理を追加すれば良いのでしょうか?
dem0nmichik0

2018/12/20 04:06 編集

具体的には,各画面に初期化関数(Init)があり,画面共通の処理が「画面を中央に表示する」,画面毎に異なる処理は「拡大/縮小/閉じるボタンを表示する」などです。こんな場合,「初期化クラス」として,「初期化メソッド(画面を中央に表示する)」を作成すれば良いのでしょうか?あとはこのクラスを継承して,画面特有の処理を追加すれば良いのでしょうか?
fana

2018/12/20 04:53

{本当に共通化すべき事柄かどうか,どういう形で共通化するか,etc}は背景事情(作ってるもの)に寄りますので,「こうだ」とは言い切れませんが, その例(画面の初期化)について言えば,各画面に直接書いても良いような事柄に思えます. 仮に,「拡大/縮小/閉じるボタン」の表示非表示処理のための記述が煩雑だということであれば纏めることを考えるでしょうが,せいぜい関数化して各画面の初期化処理から呼ぶ程度で済むように思います. 些末な実装を共有することだけを目的として継承を行うのは避けます. 継承せずに済む別の方法があるならそちらを選択します.
fana

2018/12/20 05:03

例えば画面A~Fのうち,{B,C,E}の3つの画面のことを(用途か何かの分類の上で)「XXX画面」と総称することができて,且つ,総称することに意味がある(=実装上,これらの画面を「XXX画面」として取り扱う)ようであれば,{B,C,E}はXXXから派生するかもしれません.その場合,画面の位置や拡大ボタンの有無などが「XXX」であることに起因して決まる事柄なのであれば,そのコードはXXXの側に書くべき事柄になり得ます.
dem0nmichik0

2018/12/20 23:26

fana様,回答ありがとうございます。 >>その例(画面の初期化)について言えば,各画面に直接書いても良いような事柄に思えます. その通りで,仮面の初期化などはコンストラクタに書いてもいいと思っています。この初期化関数(Init)に関して言えば,各画面毎(A~F)にInitを全て宣言して,「画面を中央に表示する」は共通,「拡大/縮小/閉じるボタンを表示する」は3つの関数のみにコーディングしているので,関数化しない方がいいでしょうか?
fana

2018/12/21 01:29

うーん,そこらへんは結局,背景事情や,書き手による尺度による部分もあるでしょうから…としか. ただ,疑問点がより明確に,具体的になれば,より妥当なアドバイスをくれる人も現れるかもしれませんし,もう少し内容を絞った質問を立ててみてはいかがでしょう? (個人的には,状況が許すならば,関数化する/しない 両パターンを書いてみて様子を見るとか,とにかく「実際にやってみる」のが良いんじゃないか,とか思いますが)
guest

0

... クラス図やシーケンス図を作成 ...

plantunl を使うと簡単に書けます。

  • Visual Studio CodeとPlantUMLでソフトウェア設計図を描く方法

https://cpp-learning.com/vscode_plantuml/

最初から汎用的なものをつくるのはよくありません。
まずは動作するものを作り、コードの重複が出てきたり、リファクタする際に再利用性を高くすることを検討するとよいです。

  • 共通化という考え方はアンチパターンを生み出すだけ説

https://hachibeechan.hateblo.jp/entry/dont-think-just-make-it-abstract

投稿2018/12/20 16:54

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

クラス図やシーケンス図を作成したほうがよいのでしょうか?

課題の解決にはなりませんが、基本的にクラス図やシーケンス図を描くクセは付けた方が良いです。
最初は流れや関連付けが頭に入っていますが、段々と大きくなって混乱しますし、時間が経つと忘れます。
今なら無料でVSCodeのアドインでPlantUMLやMermaidを使って手軽に描けるので、
頭の中を整理するために描いてみると良いです。
そして無駄や重複する部分はまとめて再利用出来る様にしていけば、自然と使いやすいクラスや関数が出来るし、他の人に説明する時も図を見せれば流れや意図が大体わかるようになります。
(むしろ他人にプロジェクト全体のソースコードだけを渡しても、解読に時間がかかります。)

投稿2018/12/20 01:39

編集2018/12/20 01:43
Wind

総合スコア442

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dem0nmichik0

2018/12/20 03:38

回答ありがとうございます。 アドバイス通りにクラス図やシーケンス図を書くクセを付けようと思います。教えてくださったVSCodeを使って今思い浮かんでいるクラス図やシーケンス図を書いてみます。
guest

0

>>クラス図やシーケンス図を作成したほうがよいのでしょうか?

今の段階で浮かんでいるもので良いので軽く図にしてみて。
書くものは紙でもいいよ。

クラスの設計となると、参考書はかなり古い本だけどおすすめの本があるよ。

https://www.amazon.co.jp/%E7%8B%AC%E7%BF%92%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3C-%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE%E3%83%86%E3%82%AF%E3%83%8E%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF%E3%82%A2%E3%83%BC%E3%83%88-ebook/dp/B00V9M5R74/ref=sr_1_60?s=books&ie=UTF8&qid=1545268596&sr=1-60&keywords=C%2B%2B

投稿2018/12/20 01:20

stdio

総合スコア3307

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dem0nmichik0

2018/12/20 03:33

回答ありがとうございます。 UMLの参考書も手元にあるので,アドバイス通りに今の段階で浮かんでいるクラス図やシーケンス図を書いてみようと思います。
guest

0

再利用性が高いクラスって、利用シーンを想定し「データをどう持つか?」「インプット/アウトプットをどう汎用的にするか?」といった設計によるところが大きいので、アプリケーションの設計を学ぶと良いです。

一般的には、抽象度合いを上げることで、汎用性は高まりますが、具体的なシーンでそのまま使えるケースは減ります。(当然逆もしかり)

バランス感覚の必要な作業でもあるので、先人/先輩にバランスを教えてもらうのが良いですし、ライブラリやフレームワークがどういった単位でまとめられているか確認してみるのも良い学習になると思います。

投稿2018/12/20 05:22

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ちょっと別口から回答しておくと、そのクラスに対してテストが書きやすいように機能を分離して実装してくことで結果目的を達することができるのではないかと思います。テスト駆動開発と言うやつですね。

投稿2018/12/20 03:30

yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

データがあって、そのデータを取り扱う関数群があれば、クラスにまとめられます。

そのデータを使うところではそのクラスをインスタンス化して使えば良いので、便利です。

また、そうしておくと、「だいたい同じなんだけど、ちょっと挙動を変えたものを作りたいんだよね」という要望があれば、継承して挙動を変えたい部分だけカスタマイズすればできます。

あんまり継承しまくってごちゃごちゃすると面倒くさいので、「本当に『ここはカスタマイズしないだろう』という機能だけまとめたクラスを作って、そこから子と孫を作って用途ごとに特化させて……」と整理したくなってくることでしょう。


逆に言うと、自分のプログラムで何を「データ」とみなすのかを理解していて、その「データ」に対する操作を関数として(コピペされまくったすぐに共通化できるコード片としてでも良いですが)書いている、という状況でないと最初の一歩を踏み出せません。

現状のコードがあまり綺麗でないのなら、クラスを使わずにリファクタリングする方が先かもしれません。

投稿2018/12/21 02:56

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問