我读过以下关于工厂模式here的文章
请参阅简短的类注册-避免反射。
这个版本实现了工厂和混凝土产品之间的减少耦合,而没有反映。
所以,我试图自己实现这个版本,但没有成功。
原因是没有启动具体产品类的静态初始化程序,因此它们没有在hashmap中注册,因此使用createProduct方法调用createProduct实例没有成功。
当我在工厂之外的客户端初始化一些具体类时,这导致静态初始化程序启动,而具体类注册得很好。之后,我调用了ProductFactory.getInstance().createProduct(productID),最后创建了混凝土类。
因此,的问题是:
这个网站的例子遗漏了什么吗?
在给定的示例中如何触发静态初始化器?
与此示例相关的代码是(从站点):
abstract class Product
{
public abstract Product createProduct();
...
}
class OneProduct extends Product
{
...
static
{
ProductFactory.instance().registerProduct("ID1", new OneProduct());
}
public OneProduct createProduct()
{
return new OneProduct();
}
...
}
class ProductFactory
{
public void registerProduct(String productID, Product p) {
m_RegisteredProducts.put(productID, p);
}
public Product createProduct(String productID){
return ((Product)m_RegisteredProducts.get(productID)).createProduct();
}
}发布于 2014-03-02 19:15:19
是的,它们遗漏了一些东西,就像在反射示例中,类必须先由客户端加载,否则它不会在工厂注册,我不认为这是一种非常干净的方法,因为工厂客户端将不得不在请求类之前加载类,使productId变得非常无用,并将客户端与特定的产品实现耦合。
我喜欢他们(不公平)所称的noob implementation --我认为它是使用最广泛的,而且有了很好的理由,它更简单,而且您实际上可以在客户端不知道它的任何情况下封装和集中创建对象,但是不知道特定产品的id (没有直接的类加载),当您计划让ProductFactory客户端注册新产品实现而不必修改工厂本身的代码时,其他实现是有用的,但在大多数情况下,当新的实现出现时,您会发现修改工厂并不是什么大事。
因此,总而言之,noob implementation根本不是noobie,它只是更简单,适合某些用例。一般来说,在这种情况下,我不认为有更好或更糟的或noobie实现,只是有不同的需求和用例。
提示:为productId使用枚举而不是字符串更干净和安全,当然,如果每次出现新的产品实现时都可以修改枚举。
https://stackoverflow.com/questions/22131430
复制相似问题