什么时候在对象中使用工厂方法而不是factory类是一个好主意?


当前回答

当它们返回的对象类型具有私有构造函数时,当不同的工厂类在返回的对象上设置不同的属性时,或者当特定的工厂类型与其返回的具体类型耦合时,工厂类非常有用。

WCF使用ServiceHostFactory类来检索不同情况下的ServiceHost对象。IIS使用标准的ServiceHostFactory来检索.svc文件的ServiceHost实例,但是WebScriptServiceHostFactory用于向JavaScript客户端返回序列化的服务。ADO。NET Data Services有自己特殊的DataServiceHostFactory和ASP。NET有它的ApplicationServicesHostFactory,因为它的服务有私有构造函数。

如果只有一个类在使用工厂,那么可以在该类中使用工厂方法。

其他回答

这真的是个品味问题。工厂类可以根据需要进行抽象/接口,而工厂方法是轻量级的(而且往往是可测试的,因为它们没有定义的类型,但它们需要一个众所周知的注册点,类似于服务定位器,但用于定位工厂方法)。

如果你想在使用方面创建一个不同的对象。它很有用。

public class factoryMethodPattern {
      static String planName = "COMMERCIALPLAN";
      static int units = 3;
      public static void main(String args[]) {
          GetPlanFactory planFactory = new GetPlanFactory();
          Plan p = planFactory.getPlan(planName);
          System.out.print("Bill amount for " + planName + " of  " + units
                        + " units is: ");
          p.getRate();
          p.calculateBill(units);
      }
}

abstract class Plan {
      protected double rate;

      abstract void getRate();

      public void calculateBill(int units) {
            System.out.println(units * rate);
      }
}

class DomesticPlan extends Plan {
      // @override
      public void getRate() {
            rate = 3.50;
      }
}

class CommercialPlan extends Plan {
      // @override
      public void getRate() {
            rate = 7.50;
      }
}

class InstitutionalPlan extends Plan {
      // @override
      public void getRate() {
            rate = 5.50;
      }
}

class GetPlanFactory {

      // use getPlan method to get object of type Plan
      public Plan getPlan(String planType) {
            if (planType == null) {
                  return null;
            }
            if (planType.equalsIgnoreCase("DOMESTICPLAN")) {
                  return new DomesticPlan();
            } else if (planType.equalsIgnoreCase("COMMERCIALPLAN")) {
                  return new CommercialPlan();
            } else if (planType.equalsIgnoreCase("INSTITUTIONALPLAN")) {
                  return new InstitutionalPlan();
            }
            return null;
      }
}

GOF定义:

定义一个用于创建对象的接口,但是让子类来决定实例化哪个类。工厂方法允许类延迟实例化到子类。

一般例子:

public abstract class Factory<T> {

    public abstract T instantiate(Supplier<? extends T> supplier);

}

具体类

public class SupplierFactory<T> extends Factory<T> {

    @Override
    public T instantiate(Supplier<? extends T> supplier) {
        return supplier.get();
    }
}

实现

public class Alpha implements BaseInterface {
    @Override
    public void doAction() {
        System.out.println("The Alpha executed");
    }
}

public class Beta implements BaseInterface {
    @Override
    public void doAction() {
        System.out.println("The Beta executed");
    }
}

public interface BaseInterface {
    void doAction();
}

public class Main {
    public static void main(String[] args) {
        Factory<BaseInterface> secondFactory = new SupplierFactory<>();
        secondFactory.instantiate(Beta::new).doAction();
        secondFactory.instantiate(Alpha::new).doAction();
    }
}

短暂的优势

您正在分离可以变化的代码和不变的代码(即,使用简单工厂模式的优点仍然存在)。这种技术可以帮助您轻松地维护代码。 你的代码不是紧密耦合的;因此,你可以随时在系统中添加新的类,如Lion、Beer等,而无需修改现有的体系结构。因此,您遵循了“修改封闭,扩展开放”的原则。

当它们返回的对象类型具有私有构造函数时,当不同的工厂类在返回的对象上设置不同的属性时,或者当特定的工厂类型与其返回的具体类型耦合时,工厂类非常有用。

WCF使用ServiceHostFactory类来检索不同情况下的ServiceHost对象。IIS使用标准的ServiceHostFactory来检索.svc文件的ServiceHost实例,但是WebScriptServiceHostFactory用于向JavaScript客户端返回序列化的服务。ADO。NET Data Services有自己特殊的DataServiceHostFactory和ASP。NET有它的ApplicationServicesHostFactory,因为它的服务有私有构造函数。

如果只有一个类在使用工厂,那么可以在该类中使用工厂方法。

我简短的解释是,当我们没有足够的信息来创建一个具体的对象时,我们使用工厂模式。我们要么不知道依赖关系,要么不知道对象的类型。我们几乎总是不知道它们因为这是运行时的信息。

示例:我们知道我们必须创建一个车辆对象,但我们不知道它是飞行还是在地面上工作。