Strategyパターンを用いた実装について
現在Javaを勉強しており、
Strategyパターンを用いた以下の実装を考えています。
public class UseStrategy {
private Strategy strategy;
public void doSomthing(int num) {
switch (num) {
case 0:
strategy = new AlphaStrategy();
break;
case 1:
strategy = new BetaStrategy();
break;
case 2:
strategy = new GammaStrategy();
break;
}
// 変数strategyを用いて処理を続行していく
// ...
}
private interface Strategy {
public abstract void method_1();
public abstract void method_2();
}
private class AlphaStrategy implements Strategy {
@Override
public void method_1() {
//do something
}
@Override
public void method_2() {
//do something
}
}
private class BetaStrategy implements Strategy {
@Override
public void method_1() {
//do something
}
@Override
public void method_2() {
//do something
}
}
private class GammaStrategy implements Strategy {
@Override
public void method_1() {
//do something
}
@Override
public void method_2() {
//do something
}
}
}
つきましては、以下ご質問させてください。
(1)Strategyパターンの実装において、
上記UseStrayegyクラスのように、あるクラスの入れ子クラスとして
Strategyインターフェース及び、その実装クラスを実装する方法は
普通でしょうか?
それとも、入れ子クラスとしてではなく、Strategyインターフェース、
その実装クラスを全て 別クラスファイルに分けた方が良いのでしょうか?
(2)例として、
BetaStrategy.method_2()とGammaStrategy.method_2()の処理が全く
同じだったとします。その場合、共通となる処理を一つのメソッド化し、
そのメソッドをBetaStrategy.method_2()とGammaStrategy.method_2()から
コールしたいと考えております。
その際、共通となる処理メソッドの実装箇所としては、以下のいずれが良いのでしょうか。
(A)Strategyインターフェースを抽象クラス化し、二つの共通処理メソッドを実装する。
(B)UseStrategyクラスに、共通処理を実装する。
それとも、上記の様なケースがある場合Strategyパターンは不適切でしょうか。
文面に分かりづらい面や、Javaのオブジェクト指向・デザインパターンについて
理解の乏しいところがあるかと思いますが、ご回答の程よろしくお願いいたします。
No.1ベストアンサー
- 回答日時:
(1)
ありえないわ。
そもそもinterfaceをprivateな内部interfaceとして定義する必要がないわ。
拡張性を考えたらすべて別クラスとして定義するべきね。
UseStrategyクラスが膨大なコーディング量になってしまうわ。
気持ちは分からなくもないのよ。
・利用者にはUseStrategyのみを意識してもらう
・Strategyの各クラスは公開したくない
っていう考え方でしょう?
だったらprotectedにでもすればいいし
あとのメンテを考えたら分けた方がいいわよ。
(2)
これはStrategyとは関係ない話ね。
答えは、
Strategyとは関係ない別クラスを作成し、その中に処理を記述しそれをコールする
よ。
BetaStrategyとGammaStrategyが持つ意味が一部共通なため
同じ処理になるというのであれば、
この2つの親クラスを作成し、そこに実装するのもありね。
でも、特にそうでないというなら
再利用性も考えて先に書いたやり方をするのがいいわ。
ご回答いただきありがとうございます。
お礼の方遅くなりまして申し訳ありません。
>気持ちは分からなくもないのよ。
>・利用者にはUseStrategyのみを意識してもらう
>・Strategyの各クラスは公開したくない
>っていう考え方でしょう?
見事に。。上記のように考えて、質問に記載したコードを書きました。
ただ、ご指摘にありますように、今後のメンテ、拡張することを考慮し
別クラスにしようと思います。
>これはStrategyとは関係ない話ね。
>答えは、
>Strategyとは関係ない別クラスを作成し、その中に処理を記述しそれをコールする
>よ。
ご指摘の通りだと思います。#自分の頭が固かったと思います。。。
無理にでもStrategy内に押し込もうしか考えておりませんでした。
再利用性、拡張することを考え、別クラスを作成しようと思います。
再度自分の書いたコードを見直すと、
色々、考慮不足のコードだったと思います。
#書いた当時はこれしかないのではないかと思っていましたが。。。
ご回答頂いた内容から、検討の足りない面がわかりました。
是非今後に活かしていきたいと思います。本当にありがとうございました。
No.2
- 回答日時:
Java では'_'は、定数を表す識別子を構成する単語の間以外には使わないのが一般的です。
ほかは、#1の方が仰っている通りです。
interface Strategy {
void method1();
void method2();
}
class AlphaStrategy implements Strategy {
public void method1() {
System.out.println("method1 in AlphaStrategy");
}
public void method2() {
System.out.println("method2 in AlphaStrategy");
}
}
class BetaStrategy implements Strategy {
public void method1() {
System.out.println("method1 in BetaStrategy");
}
public void method2() {
System.out.println("method2 in BetaStrategy");
}
}
// Gamma extends Beta
class GammaStrategy extends BetaStrategy {
public void method1() {
System.out.println("method1 in GammaStrategy");
}
}
class SomeThing {
private Strategy strategy;
void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
void doMethod1() {
strategy.method1();
}
void doMethod2() {
strategy.method2();
}
}
public class SomeThingUser {
public static void main(String[] args) {
SomeThing someThing = new SomeThing();
someThing.setStrategy(new AlphaStrategy());
someThing.doMethod1();
someThing.doMethod2();
someThing.setStrategy(new BetaStrategy());
someThing.doMethod1();
someThing.doMethod2();
someThing.setStrategy(new GammaStrategy());
someThing.doMethod1();
someThing.doMethod2();
}
}
ご回答頂きありがとうございます。
回答が遅くなりまして、申し訳ありません。
>Java では'_'は、定数を表す識別子を構成する単語の間以外には使わないのが一般的です。
つい、C言語の癖で、'_'を付けていました。
今後は、'_'を付けないように気をつけたいと思います。
また、(1)、(2)の疑問・問題を解決したコードを提示頂きありがとうございます。
提示頂きましたコードを参考に、自分のコードを書き直したいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java javaのクラスの分け方について質問です。 APIの内部用と外部用でクラスを分けたいのですがインター 2 2022/04/26 16:06
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- Java java 飾子を付けること(public static・・・) ・コンソールへの出力処理はmainメ 2 2022/06/16 19:34
- 英語 この英訳は合っていますか? 2 2022/04/29 12:12
- Java java final 1 2022/06/10 22:49
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- C言語・C++・C# 大量のデータを読み込んで表示する速度を改善したい 8 2023/05/07 13:29
- PHP アップロード画像数でCSSを分けることに成功したのですが、画像の横に文字を並べることが出来ません。 3 2023/07/28 17:16
- Java javaの質問です 次の機能を有するメソッド4つを自クラスに作成し、実装したいです 【機能】 足し算 1 2022/06/15 17:49
- Java java 次の機能を有するメソッドを自クラスに作成し、実装したいです。 機能 名前判定機能 →名前が 3 2022/06/16 16:08
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数内の変数に<summary>コメン...
-
クラス間でのデータ参照
-
a href="..." とServlet
-
範囲外の数値を代入したらエラ...
-
c++,ある関数のクラスから別の...
-
無名パッケージからのインポート
-
構造 他のクラスの構造体を別...
-
JTableのイベント取得方法
-
ネストしたenumへのリフレクシ...
-
型Containerのメソッドadd(S...
-
C#にて別クラスの関数を使いたい
-
C# インターフェイスの実装
-
C#のクラスライブラリでメッセ...
-
visual studioのデザイナ画面で...
-
ASP Pageの孫継承のPage_Load
-
親クラスから子クラスへアクセス。
-
java-別クラスの変数の使い方を...
-
Java インスタンス作成のイベ...
-
Javaでswingの画面変わる際に他...
-
【ASP.NET MVC3】共通ビュークラス
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
クラス間でのデータ参照
-
範囲外の数値を代入したらエラ...
-
関数内の変数に<summary>コメン...
-
c++,ある関数のクラスから別の...
-
C#にて別クラスの関数を使いたい
-
java-別クラスの変数の使い方を...
-
C++でfriendクラスにしているの...
-
a href="..." とServlet
-
親クラスから子クラスへアクセス。
-
構造 他のクラスの構造体を別...
-
Java リフレクションについて
-
import と extends について
-
C#でほかのファイルにある自作...
-
C#のクラスライブラリでメッセ...
-
Java
-
アップキャスト、ダウンキャス...
-
無名パッケージからのインポート
-
違うクラスからの変数の共有化
-
SwingでgetContentPaneのエラー...
-
ひとつのファイルにクラスは1つ?
おすすめ情報