質問は以下の2つです。
1.以下のようなPersonクラスを、プロパティだけを定義したクラス、メソッドだけを定義したクラスに
分離することは、クラス設計の考え方としてアリでしょうか。ナシでしょうか。
※プロパティのみ定義したクラスに分けることで、保守性を高める、など
そういったデザインパターンがあるのでしょうか
2.GetFather()メソッドのように、自分のインスタンスとは直接関係の無いデータを提供するメソッドは、
Personクラスの中に定義してはダメでしょうか。(オブジェクト指向に違反しているのでしょうか)
記載内容に不足ありましたら、ご指摘いただけると幸いです。
何卒よろしくおねがいいたしますm(_ _)m
■補足情報
使用している技術は、.NET Frameworkと、WPFです。
MVVMで設計し、ViewのDatagridに、List<Person>を表示することを想定しています。
※Entity FrameworkやDataTableは使いません。
C#
1class Person{ 2 // 名前 3 public string FirstName{get; set;} 4 // 苗字 5 public string LastName{get; set;} 6 // 子ども 7 public List<Person> Children{get; set;} 8 9 // コンストラクタ 10 public Person(){ 11 this.FirstName = string.Empty; 12 this.LastName = string.Empty; 13 this.Children = new List<Person>(); 14 } 15 // 氏名を返します 16 public string GetFullName(){ 17 string FullName = this.FirstName + this.LastName; 18 19 return FullName; 20 } 21 22 // 引数のpeopleから父親を返します 23 // 見つからない場合はnullを返します 24 public Person GetFather(List<Person> people){ 25 // Fatherをnullで初期化します 26 Person Father = null; 27 28 foreach(Person person in people){ 29 // personの子どもを確認していきます。 30 foreach(Person child in person.Children){ 31 // 子と自分の氏名が一致した場合は、子の親が自分の父親です 32 if(child.GetFullName() == this.GetFullName()){ 33 Father = person; 34 break; 35 } 36 } 37 } 38 39 return Father; 40 } 41} 42 43
データベースへのアクセスかと思いますが、どのような技術を使っているかを書いた方が回答がつきやすいのではないかと思います。
Entity Framework や DataTable を使わないということですよね?
ご質問ありがとうございます。
はい、Entity FrameworkやDataTableは使用しません。
使用している技術としては、.NET Framework, WPFです。
WPF画面のDataGridにPersonクラスのリストを表示することを想定しています。
よく意味がわかりませんが、DTO と DAO はそれぞれ何の略で何に使うものですか? データベースではなさそうですが。
■DTO:data transfer object
プロパティのみ定義し、メソッドは定義しない。
■DAO: data access object
dtoを利用するメソッドのみ定義し、プロパティは定義しない。
になります。オブジェクト指向のオブジェクトを、更に細分化する感じでしょうか。。
(すみません、私自身もよく分かっていなく。。)
> オブジェクト指向のオブジェクトを、更に細分化する感じでしょうか。。
いえ、データアクセスの目的に使うために特定のデザインパターンに沿うよう作るものです。C# ではあまり使われません。
というと語弊がありますね。DAO を自分で作ることはめったにありません。
ありがとうございます。
ということは、質問のようなPersonクラスをDTOやDAOに分けること自体、
そもそもナンセンスということなのでしょうか。
オブジェクトを DTO と DAO に分けるというのはどこからの情報なんでしょうか?
どこからの情報、ということはないのですが、
オブジェクトをDTOやDAOに書き分けるとしたら、どのようになるのかを知りたかったです。
そもそも、そういう分け方が不可能というか、考え方がおかしいのでしょうか。。
そうですね。どこからの情報かというのがわかるなら真意を読み解くこともできるかもしれませんが、それがないのであれば、どうしてそうなったのかわかりません。
ありがとうございます。
>>真意を読み解くこともできるかもしれません
この質問を起票した発端としては、「プロパティとメソッドを分離したい」という個人的な考えからです。
色々と調べたところ、DTOやDAOというの考え方が在ると知ったのですが、
実際にそれをPersonクラスに適用するにはどうすればよいか分からず、質問をさせていただきました。
そもそも「プロパティとメソッドに分ける」という考えがおかしい場合はその旨をご指摘いただけると助かります。
では質問を編集し、DAO/DTO パターンの意味を尋ねるものに変更してみてはどうでしょうか?
そうすれば回答がつくのではないかと思います。
https://ja.wikipedia.org/wiki/Data_Access_Object
https://ja.wikipedia.org/wiki/Data_Transfer_Object
ありがとうございます。質問1の内容を訂正しました。
記載内容に不足ありましたらご指摘いただけると幸いです。
> 1.以下のようなPersonクラスを、DAO/DTOパターンに書き分けることは可能でしょうか。
書き分けるというところにまず違和感があります。DAO/DTO パターンがどういうものか概略をまず知らなければどうにもならないと思うので、それを尋ねたらどうかという提案でした。
なるほどです。すみません。よくよく考えると私としては、
DAO/DTOパターンを知りたいというよりも、Personクラスをプロパティクラスと
メソッドクラスに書き分けるという考え方が、アリかナシかを尋ねたいものでした。
(それをDAO/DTOという言葉に勝手に置き換えてしまっていました)
上記に沿って、質問の内容を訂正しようと思います。
回答後になりますが、
> 「プロパティとメソッドを分離したい」という個人的な考え
なぜそう考えたか、分離することによって何の問題が解決すると考えているのかが知りたいです。するとその辺りに関する回答ができるかもしれません。
DAO と DTO がなぜ分離されるかと言うと、データベースは複数の種類があり、その違いを吸収するためです。つまり、あるデータベースに依存した DAO を別の DAO に取り換えても DTO は変更の必要がありません。これにより保守性が高くなります。DTO はデータにのみ依存するのでメソッドが必要ないのです。
一方、GetFather や GetFullName は Person に依存しており、分割する意味がありませんし、取り換える意味もありません。
分割する時には、分割された双方の依存を可能な限り小さくし、部品の取り替えを容易にするよう心掛ける必要があります。何も考えず機械的にメソッドだからプロパティだからという理由で分けるというデザインパターンは無いと思います。あるとすればそれは人間ではなく、IDE などのツールからの使用を前提としたものでしょう。
ただし、それはオブジェクト指向の話です。関数型であればまた別のデザインパターンがありますから、それを主軸に据えて設計するのであれば、結果的にメソッドとプロパティが分離されるということもあるでしょう。しかしそれはあくまでも「結果として」であり、最初から目指すものでも、原理主義的にこうでなければならないとルール付けするものでもないと思います。
>>BlueOxyさん
>なぜそう考えたか、分離することによって何の問題が解決すると考えているのか
分離することによるメリットとして考えていたことは、主に以下の2つです。
ただ、いま思うと、2つとも主観的な内容(個人的なこだわり)ばかりかなと思っております。。
1.プロパティのみ定義したクラスを作ることで、見栄えがスッキリする。
2.メソッドは開発途中にあれこれ追加/変更/削除がありそうですが、
プロパティはそうそう顔ぶれが変わることは無さそう?なので、
プロパティとメソッドでクラスを分けることで誤ってプロパティを変更してしまうリスクを避ける。
>>Zuishinさん
ありがとうございます。DAOとDTOが分離されることと、
Personクラスのメソッドとプロパティを分離しようとすることは、全然意味が違うのですね。
DAO/DTOの考え方を、このPersonクラスに適用しようとすること自体が誤りであると理解でき、スッキリしました。
おっしゃるとおり、DAO/DTOパターンを意識しすぎるあまり、
「なぜ分離するのか」をきちんと理解せず、手段が目的になってしまっていました。
(意識している割に理解できていないところが更に情けないです)
回答1件
あなたの回答
tips
プレビュー