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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

7回答

9542閲覧

javaで実装上特に不要だがinterfaceを継承する設計

退会済みユーザー

退会済みユーザー

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

4クリップ

投稿2016/03/16 15:25

編集2016/03/17 00:11

仮にAというinterfaceを作りそれを仮にBというクラスが継承したとします。Bのインスタンスを仮にCクラスのメソッドsetA(A a)というメソッドでCのメンバー変数にAクラスとしてセットします。コードにすると雑ですが、下記みたいな感じでしょうか。

interface Aは実装上なくても問題ないしむしろ邪魔に思えるのですが、CがBのインスタンスをAとして扱えるために余計なBのメソッドを呼べないので疎結合だからいいのだそうです。私は勉強不足の為わかった様なわからんような気分なんですが、interfaceはある程度、活用性がないと作る意味ない気がします。例えばD,E,Fのクラスがあってそれらも、Aのinterfaceを継承して他のクラスに使わせるならわかる気がします。でも、Bのみしか継承しないのだったらいらないと思うのです。

こういうのはリファクタリングのテクニックなんですか。そんなに重要なんでしょうか。テクニックの名前とかありますか。

java

1interface A {} 2 3class B implements A {} 4 5class C { 6 A a; 7 void setA(A a) { 8 this.a = a; 9 } 10} 11 12~~~~ 13 B b = new B(); 14 C c = new C(); 15 c.setA(b); 16~~~~

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

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

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

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

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

guest

回答7

0

ベストアンサー

余計なメソッドを呼べなくするのが疎結合なわけではないです。
メソッドを公開したくなければ、privateにすればいいだけなので。

疎結合とは、依存関係がない、というものです。
依存とは、import文であったり、new と書いている部分のことです。

ようは、「そのクラスが削除されたとしても、コンパイルエラーにならない」
という関係が疎結合です。

この例でいうと、Bクラスが消えても、Cクラスには影響がないということです。

つまりインターフェースを使った設計にしておくと、
呼び出し元に影響を与えずに、
必要なものはそのインターフェースを実装して追加すればいい、
不要なものは削除すればいいようになるところが嬉しいのです。

逆の密結合は、仕様変更や拡張に非常に弱く、一部のプログラムを直すだけで、
そこら中をテストし直す必要があったりと、大手術になることが多いです。

例えばD,E,Fのクラスがあってそれらも、Aのinterfaceを継承して他のクラスに使わせるならわかる気がします。

そうですね。その通りだと思います。
なので、普通はyubaさんのおっしゃっていることが多いです。
今後増えることを想定としているため、インターフェースを決めている。ということです。

###悪い例

java

1public class PC { 2 public void setKeyboard(Keyboard keyboard) {}; 3 4 public void setMouse(Mouse mouse) {}; 5} 6 7public class Keyboard {} 8 9public class Mouse {} 10

###良い例

Java

1public class PC { 2 public void setUsbDevice1(USB usb) {}; 3 4 public void setUsbDevice2(USB usb) {}; 5 6 public void setUsbDevice3(USB usb) {}; 7} 8 9public class Keyboard implements USB {} 10 11public class Mouse implements USB {} 12

現実の世界でも、周辺機器が増えたからPCに修理がいるというのは不便なわけです。

【悪い例】
プリンターを買ったから、PCにプリンタ用の穴(setPrinter)をつけてもらうように修理に出す。

【良い例】
プリンターを買ったけど線がUSBだったから、そのままPCに接続できた。
PCの修理は不要。

周辺の部品が、使う側に影響を出さないという設計がいいんです。

投稿2016/03/17 05:43

root_jp

総合スコア4666

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

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

退会済みユーザー

退会済みユーザー

2016/03/21 08:58 編集

なるほどです。後で変更を加えるときの作業で影響範囲が少なくなるので、今後の事を考えると疎結合で実装するのがいいって感じでしょうか。後、削除してもコンパイルエラーにならないという事は全く考えたことなかったのですごい納得しました。ご回答ありがとうございました。
guest

0

A,B,Cクラスを作るのが別々の人だとしたらどうでしょう?
Cクラスの作者とAクラスの作者は並行して別々に開発します。あとで結合することを考えればCの作者は「どんなクラスを作ってもいいけどBインターフェイスとして実装してくれ」とあらかじめ頼んでおけばいいわけです。

これは特殊なケースではありません。ライブラリを作る場合、ライブラリ作者がA,Cの作者にあたり、利用者がB作者に当たることになります。

投稿2016/03/16 23:43

yuba

総合スコア5568

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

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

退会済みユーザー

退会済みユーザー

2016/03/21 08:50

なるほど、チーム開発だとかなり大事そうですね。それぞれのクラスが密接だと変更が大変。また、ライブラリーだとインターフェイスが必要なわけですね。なんかわかってきた気がします。ご回答ありがとうございました。
guest

0

結果的に不要だっただけで、先にinterfaceAと受け入れクラスCを作って、全体を作ってから、差し込むBを作ったのだけど、実際は1つのクラスでしか使わなかった・・という感じだと、そうなります。

最終的に無駄なら削っていいわけなのですが、他人のソースコードを読むときには、どうやって作っていったのだろう・・という視点がないと何をしているのかわからないことがあります。

投稿2016/03/16 21:19

thesecret11

総合スコア234

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

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

退会済みユーザー

退会済みユーザー

2016/03/21 08:55

後の事を考えると必要って事ですね。ご回答ありがとうございました。
guest

0

疎通性ではなく疎結合ではないでしょうか?
共起語としては DI なんかでぐぐるとよいかも。
あとリファクタリングのテクニックとは言わないような… (別の用語を混ぜて覚えている??

よくある目的は、実装を交換可能にすることです。

実装を交換可能にすると

  1. A と C が汎用的な機能であれば、再利用性があがる。
  2. A が C に対し必要最小限の機能で構成されている場合、可読性が上がり理解しやすいコードになる。
  3. 目的に合わせて A の実装 (B その他クラス) を入れ替えることができる。

などが良い感じです

↑ 3. の補足ですが、例えば性能特製によって目的ごとに実装を交換するだとか
本番コードとテストコードを入れ替えやすいとかですかね

投稿2016/03/16 16:30

編集2016/03/16 16:33
heignamerican

総合スコア94

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

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

退会済みユーザー

退会済みユーザー

2016/03/17 00:10

ご回答ありがとうございます。確かに疎結合と言われていた気がします。そしてこれは、DIコンテナーのテクニックなんですか。テストコードを使ったりする時に便利なんですね。
guest

0

例にあるようなパターンの場合は、多分不要なでしょうね。

Bを渡すのに、Aを引数とするメソッドを定義している場合、いくつかの理由が考えられます。

例えば、Iteratorパターンがそうで、B以外にもCを使って似たようなことをしたいクラスが複数あり、Cで共通して使いたいメソッドをまとめたものをAとして定義した場合です。

または、例のコードとは違いますが、FactoryMethodパターンの場合にはありえます。実際のクラスを隠してわたす場合で、Bの状態変更をパッケージ内に限定したい場合などにも有効です。

Rubyやjavascriptはインターフェイスを持っていないので、実はそれほど大事なテクニックでも無いかもしれません。ですが、私は使う必要のないメソッドを晒して使う側を混乱させないようにするには良い方法だと思います。

投稿2016/03/16 16:06

iwamoto_takaaki

総合スコア2883

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

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

退会済みユーザー

退会済みユーザー

2016/03/29 15:49

ご回答、ありがとうございました。こんな〜〜パターンみたいな物があったんですね。勉強になりました。
iwamoto_takaaki

2016/03/30 07:29

他にも書いてる人がいますが、りこれらのパターンをデザインパターンと言います。 リファクタリングの際に、「ここはFactortMethodパターンをを導入しよう」などと話すとリファクタリングの方向性が一言で説明できたりします。テクニック的なものを質問されたと考えたので書きましたが、違ったと様ですね。
退会済みユーザー

退会済みユーザー

2016/03/30 12:25

すいません。質問が曖昧でした。一番知りたいのは何の為にというところでした。 ただ、そう言った具体的なテクニック名などもあるのであれば知りたかったので助かりました。
guest

0

リファクタリングというより、テクニックでしょうか。

知っている中では、Immutable Interface(イミュータブル・インタフェース)という手法と本質は同じだと思います。
下記のようなインタフェースとそれを実装したクラスがあったとします。
関数の戻り値などで、ImmutableA型を返すか、A型を返すかによって、権限機能(編集できる権限、閲覧のみの権限)などに応用できます。
(といっても、ImmutableA型をA型にキャストするような使い方をされると意味ないので、実装する側が間違えないようにするための工夫だと思ってます。
Immutable Interfaceに関して詳しい方居ましたら補足お願いしたいです。)

Java

1// インスタンスの内容を読み取り専用にするインターフェース 2Public Interface ImmutableA{ 3 public String getName(); 4 public int getNum(); 5}

Java

1Public class A immplements ImmutableA{ 2 private String name; 3 private int num; 4 5 public String getName() {return name}; 6 public int getNum() {return num }; 7 public void setName(String name) { this.name = name; } 8 public void setNum(String num) { this.num = num} 9}

投稿2016/03/16 16:05

編集2016/03/16 17:06
Odacchi

総合スコア907

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

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

退会済みユーザー

退会済みユーザー

2016/03/29 15:53

ご回答ありがとうございます。Immutable Interfaceとは、初めて聞きました。勉強になります。
guest

0

回答としては、典型的ですが、TPOによります。
設計規模、実装内容、納期、要件様々な要因によって、実装内容が変わります。

また、
デザインパターンとしてよく言われる議論の1つでもありますが、
初めのうちは以下の理由から今すぐに理解できなくてもよいと存じ上げます。
熟練者もしくは、webサイトで発信している方のコードを見るなどの癖はつけるようにしてください。

  1. そもそも必要性に迫られたことがない。(学習中であればなおのことわかりませんよね)
  2. フレームワークを利用、実装を想定した、学習するときにありがたみに気づくことがあります。

投稿2016/03/16 15:40

lib

総合スコア446

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

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

lib

2016/03/16 15:43

自分は学習中だった書籍を何度か腑に落ちるまで読み直し、何度か同じようなコードを書いたことでふとした時に気づきました。現在も鋭意精進中です。
退会済みユーザー

退会済みユーザー

2016/03/16 15:54 編集

ご回答ありがとうございます。 実はこれでも3,4年近くにJavaに触っていたりします(笑) ただ、リファクタリング!?と呼ばれるものを全く勉強したことないので、初心者マークで質問させていただきました。 確かに、ご教示頂いた、理由に関してはまだ経験したことないかもしれないので今後はっきりと理解するのかもしれないです。 参考サイトありがとうございました。
lib

2016/03/16 15:56

興味が出たことは大変良い兆候だと思います。 僕も所持はしていますが、いかにリファクタリングに関する書籍が結城先生であります。 http://www.hyuki.com/dp/ 手にとってみてはいかがでしょうか。
退会済みユーザー

退会済みユーザー

2016/03/21 09:06

ありがとうございます。これ思い切って買います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問