2010-12-16 3 views
5
class MyThing { 
    protected HashMap<String,Object> fields; 

    protected MyThing(HashMap<String,Object> newFields){ 
     fields.putAll(newFields); 
    } 

    protected Object get(String key){ 
     return fields.get(key); 
    } 
} 

少し背景。私はこのクラスをスーパークラスとして、XMLファイルからオブジェクトを表すさまざまなクラスに使用しています。これは基本的にAPIラッパーの実装であり、これをAPIとデータベースの解析済みXML間のアダプターとして使用しています。キャストはgetメソッドの呼び出し側に委譲されます。サブクラスが作成されたときや変数を返すときに何かをする必要がある場合、スーパークラスを呼び出してその後に返されるものを操作するだけです。例えば:私はこれを行う必要があるように私は感じXMLに格納されたオブジェクトの型なしラッパークラスを使用すると、これは悪いですか?

class Event extends MyThing {  
    public Event(HashMap<String,Object> newFields){ 
     super(newFields); 

     // Removes anything after an @ symbol in returned data 
     Pattern p = Pattern.compile("\\@.*$"); 
     Matcher m = p.matcher((String)fields.get("id")); 
     boolean result = m.find(); 

     if (result) 
      fields.put("id", m.replaceFirst("")); 
     } 
    } 

    public Object get(String key){ 
     Object obj = super(key); 

     if (key.equals("name")){ 
      return "Mr./Mrs. " + ((String)obj); 
     } 
    } 
} 

理由は、私は、彼らが異なる属性を持っているという理由だけでのgetId、のgetName、すべての単一のサブクラスのgetWhateverメソッドを記述する必要はありませんです。それは時間を節約し、かなり自明です。

これは明らかに「unJavalike」であり、物事をやり遂げるのに慣れ親しんだ言語の方法によく似ていますが、これを絶対にしてはいけないという論理的な理由がありますか?

+0

getString、getInt、...メソッドを記述してみませんか? – thejh

+0

これには本質的に間違ったことは何もありません。サブクラスのユーザーが特定のオブジェクトだけをクラスに入れることを知っている限り、途中でキャストしても問題はありません。 – Falmarri

+1

私はあなたのタイトルをちょっと変えました。まだあなたの意図に合っているかどうかを見てください。 :D –

答えて

2
  1. 明らかに、タイプセーフではありません。
  2. 今後のメンテナーは、どのようなタイプが想定されているのか分からず、POJOを使用していない理由について一般的に混乱します。
  3. 時間と空間の複雑さとパフォーマンスの代わりに、HashMapの特性があります。
  4. 将来的には自明ではないゲッタ/セッタを書くことは非常に困難になります。
  5. ほとんどのデータバインディングシステムは、POJO/Beans(JAXB、JPA、Jacksonなど)で動作するように設計されています。

これ以上はありますが、これは可能です。いくつかの適切なOXMライブラリを使ってみると、ずっと良いでしょう。

3

ゲッターとセッターを必要としないという理由だけで、このレベルの複雑さとオブジェクトモデルを掘り下げようとしている場合は、代わりにGroovyで行います。

Groovyは有効なJavaコードの98%を受け入れるJVM上のダック型動的言語です。したがって、あなたはすでに言語の大部分を知っています(機能を失うことはありません)... "もっと慣用的な"方法があります。物事をしているが、あなたは時間をかけてそれらを選ぶことができる。それにはすでにXmlSlurperが組み込まれています。これはおそらくあなたがやろうとしていることの大部分を占めています。

「あなたがしなければならない理由」に関しては、すべてのタイプの保守性の問題を導入しています。

  1. 新しいクラスは常にベースクラスから派生する必要があります。なぜちょうどそのメソッドとデリゲートを追加していない彼らは、あなたが基本的にはとにかくあなたのゲッターとセッターをカプセル化するために使用しているどの[)は、常に彼らは(取得オーバーライドする必要があります
  2. ベースのコンストラクタを呼び出すコンストラクタを実装する必要があります
  3. それらの他の方法]と時間をかけて劣化する可能性のある特定の論理を書く。

あなたはどうでしょうか?それはうまくいくよね?確かに。しかし、あなたはメンテナンスの悪夢を作り出しているか、ホイールを改革して間違っている可能性が高いという点で、エンジニアリングは貧弱です。

+0

私はあなたの答えが好きです。しかし、いくつかの問題があります:Groovyは私の選択肢ではありません。このスクリプトは今後の使用のために渡される予定であり、新しいGroovy構文を学びたいと思うことは間違いありません。また、サーバーや別のマシンにGroovyがインストールされていない通常のJVMでも動作しますか?私は言うことができないので。 「新しいクラスは、常にベースクラスから派生しなければなりません。なぜそれが問題なのか分かりません。 "彼らは常にベースコンストラクターを呼び出すコンストラクターを実装する必要があります" - 何を問わず独自のコンストラクターを作成する必要があります。そして... – AndrewKS

+0

3とにかく、普通のJavaのやり方であれば、ゲッターとセッターをすべて書かなければならないでしょう。しかし、代わりに、いくつかの異なるクラスに対してpublic getId(){return id;}、public getName(){return name;}構文を何度も繰り返しています。それは基本的に繰り返しコードです。 – AndrewKS

関連する問題