工厂模式:访问子方法

时间:2016-10-13 10:36:48

标签: java design-patterns

我有两个类CashStore和DrinkStore,两个都来自Store。我有一个StoreFactory类(返回Store对象)来实例化客户端的对象。我想从这些客户端访问特定于子类的方法。如何不进行铸造我怎么做?如果我使用了cast,它是否会破坏模式,因为现在客户知道Child类?

class Store{
    A(){}
    B(){}
}

class CashStore{
    A(){} 
    B(){}
    C(){}     
    D(){} 
}

//impl for drink store and other stores

class StoreFactory{
    public Store getStore(String type){
        //return a Store obj based on type DrinkStore or CashStore
    }
}


class Client{
    StoreFactory fac;

    public Client(){
        fac = new StoreFactory();
        Store s = fac.getStore("cash");
        s.C(); //requires a cast
    }
}

施法会破坏我的模式吗?

3 个答案:

答案 0 :(得分:2)

工厂模式用于从运行时类型中解耦。例如,当它是特定于平台或特定于布局时,您不希望您的客户端代码弄乱它。在您的情况下,您确实需要一个确切的类型,所以似乎工厂模式不是一个好的选择。考虑使用简单的静态方法,例如:

class Stores {
  static CashStore createCashStore() {
    return new CashStore();
  }
  static DrinkStore createDrinkStore() {
    return new DrinkStore();
  }
}

答案 1 :(得分:0)

所以基本上你需要访问子特定方法而不进行强制转换。这就是Visitor模式的全部目的。

您可以使用方法重载在不同的子节点之间切换。我在下面给出了一个例子,你需要调整它以适应你的代码。此外,您还应该从构造函数(客户端)中取出业务逻辑,并在方法中实现它们。

public class Client{

    public void doSomething(CashStore cs){
        cs.c();
        //you can call methods specific to CashStore.
    }

    public void doSomething(DrinkStore ds){
        ds.e();
        //you can call methods specific to DrinkStore.
    }

}

答案 2 :(得分:0)

  

我想从这些客户端访问特定于子类的方法。   如何不进行投射,我该怎么做?

如果你知道预期的类型,那么你可以使用泛型来避免转换:

interface Store {    
}

class WhiskeyStore implements Store {    
}

class VodkaStore implements Store {
}


class StoreFactory {
    <T extends Store> T getStore(Class<T> clazz) {
        try {
            // I use reflection just as an example, you can use whatever you want
            return clazz.getConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("Cannot create store of type: " + clazz, e);
        }
    }
}

public final class Example {
    public static void main(String[] args) {
       WhiskeyStore whiskeyStore =  new StoreFactory().getStore(WhiskeyStore.class);
       VodkaStore vodkaStore =  new StoreFactory().getStore(VodkaStore.class);
    }
}