简体   繁体   English

这是创建工厂类的更好方法

[英]Which is better way for creating factory class

I have created factory class and i wonder which is better way to implement it. 我已经创建了工厂类,我想知道哪种更好的方法来实现它。 option 1 选项1

public class Factory {

    private IProperty prop;
    public IDoc doc;

    public Factory(int version) {
        switch (version) {
            case '1':   
                prop = new Prop();
                doc = new Docu();
        ...
            case '2':
            prop = new Prop1();
            doc = new Docu1();
        ...
        }
    }

    public IProperty getProperty() {
        return this.prop;
    }

    public IDoc getDoc() {
        return this.doc;
    }
}

My question is if to do it like that ie define member with the interface type and to to switch on the constructor or for every get method to use switch statement instead on the constructor, so in the constructor i will just get the version and save it on class member and than for instance use like 我的问题是,是否要像这样用接口类型定义成员并打开构造函数,或者让每个get方法在构造函数上使用switch语句,所以在构造函数中,我只会获取版本并保存它在类成员上,比例如使用

public IProperty getProperty() {
switch (version) {
  case '1':
    prop = new Prop();
  case '2':
    prop = new Prop1();
...

So what is the better way, or any other idea? 那么,更好的方法是什么?

The most clean way is to expose what you do as two separate factories giving them a common abstract base or a reusable policy argument if they have anything to share. 最干净的方法是将您的工作公开为两个独立的工厂,如果它们有任何共享的对象,则为它们提供通用的抽象基础或可重用的策略参数。 One factory type should only create one type of particular object (say only plastic tools). 一种工厂类型应仅创建一种特定对象(例如,仅使用塑料工具)。 Factory public configuration normally only holds properties required to create objects (contacts of suppliers, patents) or static properties of objects being created (type of plastic, let's say), but not type/class of objects. 工厂的公共配置通常仅保留创建对象所需的属性(供应商的联系方式,专利)或正在创建的对象的静态属性(例如塑料的类型),而不包含对象的类型/类别。

Also, something that is a storage of long lived objects like in your example #1 should probably be called "context", not "factory". 另外,像您的示例#1中那样存储长期对象的东西可能应该称为“上下文”,而不是“工厂”。

Code example below. 下面的代码示例。

public interface IFactory {
  IDoc createDoc();
  IProp createProp();
}

public class Type1Factory implements IFactory {
  @Override public IDoc createDoc() { return new Doc1(); }
  @Override public IProp createProp() { return new Prop1(); }
}

Your second way is always better since every caller of your get* methods will receive a new instance of the object. 第二种方法总是更好,因为get*方法的每个调用者都会收到该对象的新实例。 If you create the two objects in the constructor, you will have to handle object-sharing issues (even more if you use these objects in different threads). 如果在构造函数中创建两个对象,则必须处理对象共享问题(如果在不同线程中使用这些对象,则还要解决)。

The idea of creating a factory is much better in your first version than second one. 在第一个版本中,创建工厂的想法比第二个版本要好得多。

Ideally, it shouldn't be the constructor of factory class but a static method. 理想情况下,它不应是工厂类的构造函数,而应是静态方法。

public class Factory 
{
    public static IProperty getPropertyObject(char version)
    {
        switch (version)
        {
            case '1':
               return new Prop();

            case '2'
               return new Prop1();
        }
    }

    public static IDoc getDocObject(char version)
    {
        switch (version)
        {
            case '1':
               return new Doc();

            case '2'
               return new Doc1();
        }
    }
}

It depends on your situation. 这取决于您的情况。

The first option suggests that your IProperty and IDoc have different versions but for each version of one you have a corresponding version of the other. 第一个选项建议您的IPropertyIDoc具有不同的版本,但是对于一个版本的每个版本,您都具有另一个版本。

While the second option suggests that the versions of those could be independent of each other. 尽管第二种选择表明这些版本可能彼此独立。

  • First of all, your Factory should ideally have static references instead of non-static one. 首先,理想情况下, Factory应具有static references而不non-static static references And it should have a static method to create / get the appropriate instance. 并且它应该具有static method创建/获取适当的实例。

  • Secondly, its better to have two different factories for different types. 其次,最好有两个不同类型的工厂

  • Thirdly, I would name your method as createProperty , rather than getPropertyObject , because that method is not returning the already created instance, rather its creating one. 第三,我将您的方法命名为createProperty ,而不是getPropertyObject ,因为该方法不返回已创建的实例,而是返回其创建实例。

Of course, getPropertyObject('1') , seems like it is fetching a property for that version from a persistence storage, which is not what it is doing. 当然, getPropertyObject('1')似乎是从持久性存储中获取该版本的property ,而不是它正在做什么。 It is rather creating an instance based on version. 而是根据版本创建实例。

( NOTE: - Name of static factory methods are important. They are amongst one of the advantages, they have over constructors . Since with a name , you can guess what exactly that factory method does) 注:- static factory methods名称很重要。它们是constructors优于constructors的优点之一。由于有了name ,您可以猜测factory method确切作用)

Having said that, I would say, that the 2nd option would be better with all those changes. 话虽如此,我想说,所有这些更改都会使2nd option更好。 Let the createProperty method decide, how it wants to create the instance . createProperty方法决定如何创建instance

So, I would modify your code like this: - 因此,我将这样修改您的代码:-

public class PropertyFactory {
    private static IProperty prop;

    public static createProperty(char version) {

        switch (version) {
            case '1':
                prop = new Prop();
                break;  // Don't forget a `break` here.
            case '2':
               prop = new Prop1();
               break;

            default:  // do have a default case
               prop = null;
        } 
        return prop;
    }
}

Similarly, you can create a DocumentFactory to create a document object . 同样,您可以创建一个DocumentFactory来创建一个document object Name the method: - createDocument(char version) 命名方法: createDocument(char version)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM