2012-09-12 57 views
1
package com.factory; 

import java.util.HashMap; 
import java.util.Map; 

//Factory class 
class FactoryClass { 
     Map products = new HashMap(); 

     void registerProduct(String prodId, ProductInt prodInterface) { 
      products.put(prodId, prodInterface); 
     } 

     ProductInt createProduct(String prodId) { 
      return ((ProductInt) products.get(prodId)).createProduct(); 
     } 
}  

// Client 
public class FactoryPattern { 
    public static void main(String[] args) { 
     FactoryClass factory = new FactoryClass(); 
     factory.createProduct("pen"); 
    } 
} 

package com.factory; 

//Interface Product 
public interface ProductInt { 
    ProductInt createProduct(); 
} 

// Concrete Product-1 
class Pen implements ProductInt { 
    static { 
     FactoryClass factory = new FactoryClass(); 
     factory.registerProduct("pen", new Pen()); 
    } 

    public ProductInt createProduct() { 
     return new Pen(); 
    } 
} 

// Concrete Product-2 
class Pencil implements ProductInt { 
    static { 
     FactoryClass factory = new FactoryClass(); 
     factory.registerProduct("pencil", new Pencil()); 
    } 
    public ProductInt createProduct() { 
     return new Pencil(); 
    } 

} 

当我运行这段代码,我得到空指针,因为没有产品在HashMap中注册。所以,当我要求产品实例为“铅笔”时,它找不到任何关键字来向我返回具体的Pencil类对象。任何人都可以帮我编码 - 就像Factory和具体类之间不应该有任何关系,所以注册将保持在Factory类之外,我应该得到我要求的适当的具体类对象?工厂模式的例子 - 需要解决下面的代码

感谢 巴拉吉

+0

“我得到空指针”:其中,由什么引起的? – Raedwald

回答

0

您正在创建的独立实例您FactoryClass - 所有这些情况都在其中thier自己Map products实例 - 您在main()方法创建的工厂是由您创建的工厂不同,注册您的penpencil。很明显,在FactoryClass.products中没有注册的项目。

的一种方法是在你的FactoryClassstatic申报Map products - 这将解决你眼前的问题 - 即使作为一个整体的代码似乎需要在其他地方其他方面的改进。

0

夫妇的问题:

首先,工厂方法要么是static或不同类比类创建。因此有一个interface其唯一的方法是创建接口的实例并不合乎逻辑。 InterfaceA可创建InterfaceB的实例,或者接口为通用的FactoryInterface<X>并创建X的实例。见番石榴的Supplier接口

举个例子,Pen ...能不能叫Pen.createProduct(),除非你已经拥有的Pen一个实例,因为该方法不是一成不变的。

因此,考虑到上述情况,请考虑让您的Factory采用Producer<X>Supplier<X>创建X的实例。

其次,考虑让你的工厂类别为Singleton。你遇到的问题是,每个静态初始化创建一个新的工厂实例,立即扔掉。因此,当您稍后尝试获取映射值时,您将从与其注册的实例不同的实例获取它。

最后,在类以某种方式被使用/触摸之前,不会调用类的静态初始化器。您需要调用PenPencil上的某些内容来调用它们的静态初始化块,从而注册它们自己。

0

除了上面的答案http://www.oodesign.com/factory-pattern.html说: 我们必须确保具体的产品类在工厂要求注册之前加载(如果它们没有加载,他们将不会在工厂注册并且createProduct将返回null)。为了确保它,我们将在主类的静态部分中使用Class.forName方法。

class Main { 

static 
{ 
    try 
    { 
     Class.forName("OneProduct"); 
     Class.forName("AnotherProduct"); 
    } 
    catch (ClassNotFoundException any) 
    { 
     any.printStackTrace(); 
    } 
} 
public static void main(String args[]) throws PhoneCallNotRegisteredException 
{ 
    ... 
} 
}