2012-03-13 20 views
1

ジェネリックスがよりスケーラビリティに優れたソリューションの設計に役立つかどうかを判断しようとしています。私のアプリケーションでは、データソースからデータをロードするモデルクラスがあり、ModelProxyクラスを使用してModelクラスのメソッドの一部を公開しています。ワイルドカードを使用したジェネリックスを使用した適切なデザイン

public interface ModelProxy { 
    public int getOrderCount(); 
    public int getCustomerCount(); 
} 

public abstract class AbstractModel { 
    public abstract ModelProxy loadData(Configuration configuration); 
} 

public class ConcreteModel extends AbstractModel { 
    public ModelProxy loadData(Configuration configuration) { 
     loadInternal(); 
     return new ConcereteModelProxy(this); 
    } 
} 

すべてがこれまでのところよさそうだが、私は(ワイルドカード)ジェネリック医薬品は私がModelProxyインタフェースまたはConfigurationクラスを拡張することができるようになるより良いソリューションを設計するのに役立つことができるかどうかを確認するために探しています。たとえば、別のConcrete Modelクラスでは、ExtendedConfigurationクラスとExtendedModelProxyを使いたいと思っています。

public ExtendedModelProxy extends ModelProxy { 
    // Additional methods 
    public int getTotalCount(); 
} 

public class ConcereteModel2 extends AbstractModel { 
    public ExtendedModelProxy loadDate(ExtendedConfiguration configuration) { 
     return new ConcreteExtendedModelProxy(this); 
    } 
} 

Java Genericsを使用すると、上記のような結果が得られますか? または私のデザインに欠陥があり、再設計する必要があるかもしれません。どんな提案も非常に役に立ちます。

おかげで、

例クライアントコード:

public abstract class Service { 
    public ModelProxy load(Configuration configuration) { 
     return getModel().loadData(configuration); 
    } 

    protected abstract AbstractModel getModel(); 
} 

public class ServiceImpl extends Service { 
    protected AbstractModel getModel() { 
     return new ConcreteModel(); 
    } 

    public static void main() { 
     Service service = new ServiceImpl(); 
     ModelProxy proxy = service.load(configuration); 
     System.out.println(proxy.getOrderCount()); 
    } 
} 

public class ExtendedServiceImpl extends Service { 
    protected AbstractModel getModel() { 
     return new ConcreteModel2(); 
    } 

    public static void main() { 
     Service service = new ExtendedServiceImpl(); 
     ExtendedModelProxy proxy = (ExtendedModelProxy) service.load(configuration); 
     System.out.println(proxy.getTotalCount()); 
    } 
} 

私はあまりと混同していないことを願っています。 ExtendedServiceImplでは、getTotalCountメソッドにアクセスできるようにModelProxyをExtendedModelProxyにキャストする必要があることがわかります。私の考えは多分キャストを避けるためにジェネリックスを使うことができたのです。何かのように

public abstract <M extends ModelProxy, C extends Configuration> M loadData(C configuration); 

多分私はものをovercomplicatingしていると本当に私の必要なすべてのデザインです。わからない...

+0

私はどのように明確ではないよ、なぜ、あなたはジェネリックを使用したいです。あなたが働きたい最小限のコードを持つ[SSCCE](http://pscode.org/sscce.html)を投稿できますか? – Bohemian

+0

これらの拡張されたクラスは、拡張されていないクラスには存在しないメソッドをクライアントに公開する必要がありますか?私が今見ているところからは、代わりにインターフェースを使うほうが良いようです。 – trutheality

+0

@ボヘミアン。私はそれをどのように使用するのかを示すためにいくつかのサンプルコードを追加しました。 – user320587

答えて

0

どのようにこの種のものについて

package jj; 

import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.Proxy; 
import java.util.*; 

interface Configuration { 
} 

interface Model { 
} 

interface OrderModel extends Model { 
    public int getOrderCount(); 
    public int getCustomerCount(); 
} 

interface CustomerModel extends Model { 
    public int getName(); 
    public int getAddress(); 
} 

abstract class AbstractModel<M extends Model> { 
    @SuppressWarnings("unchecked") 
    public M loadData(Configuration configuration) { 
     // connect to stuff 
     Object connection = null; 
     loadInternal(configuration, connection); 
     // do some other stuff 
     return (M) Proxy.newProxyInstance(null, new Class<?>[]{getModelClass()}, null); 
    } 

    protected abstract void loadInternal(Configuration configuration, 
      Object connection); 

    protected abstract InvocationHandler getInvocationHandler(Object connection); 
    protected abstract Class<M> getModelClass(); 
} 

class ConcreteOrderModel extends AbstractModel<OrderModel> { 
    public void loadInternal(Configuration configuration, 
      Object connection) { 
    } 

    protected InvocationHandler getInvocationHandler(Object connection) { 
     return null; 
    } 

    protected Class<OrderModel> getModelClass() { 
     return OrderModel.class; 
    } 
} 

class ConcreteCustomerModel extends AbstractModel<CustomerModel> { 
    public void loadInternal(Configuration configuration, 
      Object connection) { 
    } 

    protected InvocationHandler getInvocationHandler(Object connection) { 
     return null; 
    } 

    protected Class<CustomerModel> getModelClass() { 
     return CustomerModel.class; 
    } 
} 
関連する問題