PHPで開発していて下記のようなデータを取り扱っています。
■スペック情報
[共通][素材][ボディ] = ステンレス
[共通][素材][ベルト] = レザー
[共通][付属品][専用BOX] = あり
[共通][付属品][説明書] = あり
[バリエーション][カラー][ボディ] = ブラック
[バリエーション][カラー][ベルト] = ブラウン
[バリエーション][サイズ][幅] = 46mm
[バリエーション][サイズ][ベルト長] = 18cm
※データは一例で内容は変化します
これを配列を使って処理していますが、クラスとして定義して扱い易くしたいと考えています。
ただ今の私の知識では最終的にこのクラスが配列を出力してforeachで回すくらいしか思いつかず、それだと配列をクラスで囲っているだけであまり便利にならないような気がします。
データをオブジェクトとして取り扱えるだけでも、そのデータの意味や目的がはっきりするという部分でメリットはあると思いますが、他に何か利便性が向上するようなメリットはあるのでしょうか?
漠然とした質問で恐縮ですが、何卒よろしくお願いします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+5
配列をオブジェクトにするメリット
オブジェクトにすると、いろいろなメリットがありますが、
たとえば、そのオブジェクト用にメソッドが使えるようになります。
(ちなみに、これはPHPの配列がプリミティブ型だからそういう仕様ですが、
Rubyの配列はオブジェクトなので、mapなど配列用のメソッドが使えます)
するとたとえば、「mmとcmを変換する」といった処理を、
オブジェクト自身でできるようになるわけです。
それの何が良いのかというと、プログラムが大規模になったとき、
たとえば関数が千とか1万とかあったら、
データに対応する処理を探すだけでも大変ですよね。
しかし、メソッドならクラスに書いてあるので、すぐ分かるわけです。
そのデータに使う処理が、データとセットになっているので便利です。
また、データの方も、グローバル変数よりもスコープを限定できます。
だから、オブジェクトにすることで、複雑性が減り、保守性が向上します。
かなり簡略化した説明ですが、これがオブジェクト指向の
「カプセル化」のメリット(のひとつ)です。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
所定のIDがわかればオブジェクトのほうがデータを抽出し易いでしょう
逆に所定の条件から特定のプロパティを取る場合は配列で十分です
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
オブジェクト指向プログラミングをしないで、オブジェクトを扱うのはあまりメリットがありません。
Cの構造体やPHPだと配列(連想配列)で十分です。
オブジェクト指向プログラミングに興味があるのでしたら、入門書がいくらでもありますので、まずはオブジェクト指向プログラミングに入門するところから始めるのが良いと思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
クラス化のメリットということではLLmanさんの回答に賛成なんですが、
PHPを数年書いてきてよく思うのですが...
PHPで書かれたサイト全体がオブジェクト指向でクラス化されていたり、
そのようなフレームワークを使われているならいいのですが、
ほとんどが手続き型になっているのに、一部の処理だけクラス化すると
処理が分散して、かえって可読性が落ちたり、メンテしにくくなったりする場合があります。
また、PHPではデータを配列で持つことは良くも悪くもよくあることなので、
あまりメリットがわかないなら、無理にクラス化しなくてもいいような気がします。
グローバルなarray_xxx関数もとても豊富ですしね...
※デメリットについてなので、若干趣旨がずれますが
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
横から失礼します。
msx2様、icchil様、回答欄に質問するご無礼をお許し下さい。
考え方としては、オブジェクト指向の勉強をしたのが10年前で何分知識不足ですが、配列にデータの参照アドレス(識別子)を格納し、クラス、及びメソッドとデータを切り離し、クラス、及びメソッドはオブジェクトを参照し処理を扱えるイメージでよいでしょうか?
オブジェクトと言う一意の共有資産をパブリックやプライベート変数(PHPの呼び名であるか不明ですが、)、配列などをクラス(店)、メソッド(料理人)に格納し調理し出力(料理を出す)する。上記の変数、または配列はPCで言うとこのメモリ(作業台、または冷蔵庫)と同じイメージを持ちます。
スコープは上記の例えでいうところの店内。
データの無駄な複製を排除して一意性を確保しつつデータを扱える点にメリットがあるように思えました。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
max2様➡❌
msx2様➡〇
大変失礼しました。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.11%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/09/29 10:02
オブジェクト用にメソッドが使えるのはメリットですね。
データのまとまりに意味があり、データの構造も変更になる可能性が大なので、とりあえずプログラムからは「スペック情報」というオブジェクトを取り扱う様にして、その中身はオブジェクトで決まる感じにできたら便利かなと考えました。
ただ、その実装方法が今のところ手探りで(他の回答にもありましたが)オブジェクトにすることで逆に複雑さが増してしまう可能性が高いと思います。
オブジェクト指向に関しては知識は少ないですが、現状の私が感じる問題点としては、配列でデータを取り扱うと配列を作る側と使う側で構造を把握しておく必要があり、データ構造が変更になった場合に正しくデータを取り出せなくなることです。現状はforeachを入れ子にして自分でもよくわからないループでデータを取り扱っていますので…。
長々としたコメント失礼しました。
コメントを考えることで頭の中が少し整理されてきたような気がします。
ありがとうございました。
2016/09/29 20:27 編集
>オブジェクトにすることで逆に複雑さが増してしまう
たしかに短期的にはそうですが、OOは長距離走の走り方なんです。
いわば「ウサギとカメ」で、大規模・長期間・多人数になるほど、
「変更に強い」という、オブジェクト指向の真価を発揮します。
>配列を作る側と使う側で構造を把握しておく必要
OOの「カプセル化」が正しくできていれば、
使用側が構造を把握する必要がなくて済みます。
ふだんOOと意識せず使う「クラスライブラリ」がそうですよね。
内部構造が分からなくても、APIからメッセージを送れば済みます。
(ただし、使う側は楽ですが、作る側は大変です)
>foreachを入れ子にして自分でもよくわからないループ
https://teratail.com/questions/49324
入れ子の外し方のサンプルコードとしては、上記の私の回答がそうです。
ただこれを見て、「逆に複雑さが増して」いると思うかもしれません。
たしかに冗長な書き方ではあります。しかし、メリットとしては、
「search_position」など、部分的な単体テストが書けます。
(この例では過剰でしょうが、もっと複雑な場合テストしたくなります)
また、「4 → 5までの合計」などと仕様変更するときに、
部品に分解してあるので、変更が容易になります。
入れ子だと芋づる式につながり、全体の把握と変更が大変です。
まあ、全部こういうスタイルで書くのもしんどいと思いますが、
5重、6重……と、制御文の多重入れ子にガマンできない場合だけでも、
リファクタリングで入れ子を崩せば、メンテしやすくなるでしょう。
2016/09/30 00:30
まさにカプセル化は私の目指すところでした。まだまだ知識不足ながらオブジェクトにすることのメリットも知ることができました。
また、リンク先のサンプルソースも拝見させて頂き、正直なところ理解はできていませんが、このソースにもしかしたら私の疑問に思っている「配列構造をどうやってオブジェクトで表現するのか?」の答えがあるように思えてなりません。
入れ子の崩し方というのが全くもってピンとこないのですが、こういうやり方もあるんだと分かれば新しい切り口で調べることもできます。(補足いただけると大変有難いです…汗)
いつも丁寧な回答に感謝しています。
今後もよろしくお願い致します。
2016/09/30 02:33
それは具体的には「デザインパターン」でいう「イテレータ」ですね。
やはり配列より複雑になりますが、カプセル化できるのと、
走査の仕方を独自のものに変えられるメリットがあります。
走査が複雑化すると、入れ子になるしデータも壊れやすいです。
だから、複雑な処理を走査メソッドに分解していくわけです。
>入れ子の崩し方というのが全くもってピンとこない
マーチン・ファウラーの『リファクタリング』を読むと、
単純化の方法がいろいろ載っているので、その応用です。
ただ、リファクタリングやデザインパターンの本は、
Javaで書かれていることが多いです。
大規模開発はJavaで書かれるから、OOの需要もあるわけです。
今のOOの本場がJavaですから、Javaが読めると学習効率が良いです。
>今後もよろしくお願い致します。
よろしくお願いいたします。