- ベストアンサー
JAVAのオブジェクト指向で処理分岐
- JAVAのオブジェクト指向で処理分岐する方法について教えてください。
- Testクラスの機能をTest1とTest2というクラスに分けて呼び出し側からコードを書き換える必要がないようにする方法を教えてください。
- スマートなやり方でTest1とTest2のコンストラクタでTestクラスの実体を分岐する方法を教えてください。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 質問内容を読み違えてたらすいません。 携帯のキャリアを例にしたオブジェクト指向的な感じの場合私ならこう作ってみます。 (他にももっと良い作り方あるかもしれません) (インデントは全角スペース使ってますのでコピペではエラーになります) ==== Carrierクラス(抽象) abstract public class Carrier { abstract public String getMessage(); } ==== CarrierDoCoMoクラス(Carrierクラスのサブクラス) public class CarrierDoCoMo extends Carrier { public String getMessage() { return "ドコモ"; } } ==== CarrierAuクラス(Carrierクラスのサブクラス) public class CarrierAu extends Carrier { public String getMessage() { return "AU"; } } ==== CarrierFactoryクラス(適切なキャリアクラスを生成する) public class CarrierFactory { /** ドコモ */ public static final int CARR_TYPE_DOCOMO = 1; /** AU */ public static final int CARR_TYPE_AU = 2; public static Carrier createCarrire ( int carrierType ) { if ( carrierType == CARR_TYPE_DOCOMO ) { return new CarrierDoCoMo(); } else if ( carrierType == CARR_TYPE_AU ) { return new CarrierAu(); } return null; } } ==== CarrierTestクラス(動作確認用) public class CarrierTest { public static void main ( String[] args ) { Carrier carrier = CarrierFactory.createCarrire(CarrierFactory.CARR_TYPE_DOCOMO); System.out.println ( carrier.getMessage() ); carrier = CarrierFactory.createCarrire(CarrierFactory.CARR_TYPE_AU); System.out.println ( carrier.getMessage() ); } } この作りですとキャリアのタイプを判断する条件式が入ってしまいます。 CarrierFactory#createCarrierにユーザエージェント等を渡すようにしてあげてcreateCarrierメソッド中でキャリアを判別し、適切なクラスを返すようにすると呼び出し側のクラスに条件式を書く必要がなくなります。 (質問内容にある渡そうとしているdataにキャリアがわかる情報を持たせるようにするイメージです) そうすればCarrierFactory#createCarrierから自動的に適切なCarrierクラスが返ってきますので条件分岐とか必要なくgetMessage()を呼び出すとドコモまたはAUのメッセージが返ってきます。 他にキャリアを追加したければCarrierを継承したクラスを作成しCarrierFactory#createCarrierに条件を追加して返してあげるようにすればOKです。 これで呼び出し側では条件分岐等何も意識せずにそれぞれの処理が書かれたメソッド(例ではgetMessage())を呼び出すことが出来ます。 長々と書きましたが違っていたら申し訳ないです。 他にも作り方あるかもしれませんので参考程度にお願いします。
その他の回答 (2)
- taka451213
- ベストアンサー率47% (436/922)
こんばんは。 結構難問ですな・・・。 >呼び出し側からはコードを書き換える必要の >内容にしたいのです。 つまり、 test = new Test(); test.setData(data); ここは一切手を入れないという意味ですか? こうなるとinterfaceやabstractで何とかなるような事じゃないですね・・・。 Test.class側で何とか吸収しないといけないので、 Test.classのコンストラクタで条件分岐し、自身のメンバ変数に、対象のobjectをセット。 setData()メソッドで、メンバ変数のobjectに値をセット。 まぁ、このようにしかならんでしょ・・・。
- LOHA
- ベストアンサー率52% (203/388)
>Testクラスの中でTest1とTest2のコンストラクタで >Testクラスの実体をTest1かTest2に分岐するようにしたい これはどういう意味でしょう?実体を分岐とは? >呼び出し側からはコードを書き換える必要の この「呼び出し側」というのは >test = new Test(); >test.setData(data); のことですか? これを書き換えずにsetDataに渡したdataから種類を判別して、Test1クラスとTest2クラスで処理を分けたいということで合ってますでしょうか? そうであれば例えば、 >A社の携帯の場合、Test1クラスを呼び出し >B者の携帯の場合、Test2クラスを呼び出す とするならば、 class TestParent { Test1, Test2のインターフェースや共通部分の実装など } class Test1 extends TestParent { TestParentのメソッドのオーバーライド } class Test2 extends TestParent { TestParentのメソッドのオーバーライド } といったようなクラスを作っておき、Test.setData内で、dataがA社相当の物 TestParent test = new Test1() B社相当なら TestParent test = new Test2() のようにすれば良いのではないでしょうか。 他にも色々方法はあるとは思いますが、あとはデザパタの得意な方にお任せいたします。
お礼
参考にさせていただきました。 かなり遅くのお礼になって申し訳ございません。 非常に回答者様のアイデアが助けになりました。