我有两个类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
}
}
施法会破坏我的模式吗?
答案 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);
}
}