私は、シリアル通信でメッセージを使ってデバイスと通信したいJavaクライアントを持っています。クライアントは、シリアル通信の醜い詳細を抽象化して、きれいなAPIを使用できるはずです。クライアントは、そのAPIを介して多くのタイプのメッセージを送信し、応答を得ることができます。私は、このAPIを実装するのが最善の方法であるというアドバイスを探しています。簡単にするためにJavaでタイプセーフメッセージAPIを設計するにはどうすればよいですか?
、我々は2つだけのメッセージタイプを持っていると言う:HelloMessage
APIの設計InitResponse
(現実には、多くの人がもっとあります)
をトリガーHelloResponse
とInitMessage
をトリガする(つまり、のJavaの抽象化ですデバイスは)私が持っている可能性があります。メッセージの種類ごとに
一つの方法は:
public class DeviceAPI {
public HelloResponse sendHello(HelloMessage){...}
public InitResponse sendInit(InitMessage){...}
... and many more message types ....
これがうまく安全なタイプです。 (それは何度も同じである可能性がありますsend()
メソッド、オーバーロードが、それはほぼ同じです)。しかし、それは非常に明示的で柔軟性に欠けるものであり、APIを変更することなくメッセージを追加することはできません。
class HelloMessage implements Message
class HelloResponse implements Response
...
public class DeviceAPI {
public Response send(Message msg){
if(msg instanceof HelloMessage){
// do the sending, get the response
return theHelloResponse
} else if(msg instanceof ...
これはAPI(唯一の方法)を簡素化し、追加のメッセージタイプは、APIを変更せずに、後から追加することを可能にする:
Iはまた、すべてのメッセージタイプを取る単一の送信方法を有することができます。同時に、クライアントは応答タイプをチェックし、それを正しいタイプにキャストする必要があります。
クライアントコード:
DeviceAPI api = new DeviceAPI();
HelloMessage msg = new HelloMessage();
Response rsp = api.send(msg);
if(rsp instanceOf HelloResponse){
HelloResponse hrsp = (HelloResponse)rsp;
... do stuff ...
これは私の意見では醜いです。
お勧めですか?よりクリーンな結果をもたらす他のアプローチはありますか?
参考までにお待ちください。どのように他の人がこれを解決しましたか
列挙型のパラメータ化された型は可能性がありますか?または、これは不可能です(まったくありません)。 – skiwi
「レスポンス」のタイプをチェックし、HelloMessageをキャストします。それはグロテスクに見える。とにかく、実装クラスの "instanceOf"と "casting"操作を隠すことができます。 – arjacsoh
タイプをチェックする必要はないとは思わないが、これはどうやって実装するのだろう。あなたがこれを望まないなら、再考するべき正しい場所はあなたのモデルだと思います。これらの応答が異なるオブジェクトであることを必要とするのは何ですか?例えばジェネリックではありませんか? –