实现工厂方法模式的不同方法

时间:2014-08-07 10:53:00

标签: java c# oop design-patterns factory-pattern

我看到了一个Factory Method Pattern示例,其中Client类被定义为抽象类,并包含一个抽象方法(即工厂方法),如下所示:

abstract createCourse(String scheduleType);

因此,我需要扩展抽象Client类并实现createCourse方法。下面是代表客户的示例:

public abstract class CourseProvider {
    public Course startCourse(String scheduleType){
        Course course = createCourse(scheduleType);         
        course.setAvailability(true);

        return course;
    }

    abstract createCourse(String scheduleType); 
}

每次我想使用不同的工厂时,我都要扩展它。

但是,我找到了实现此模式的另一种方法here。在那篇文章中,抽象工厂方法没有在客户端内部定义(它不是更抽象的:可能是抽象的,但不是必需的),但它是在另一个代表工厂基类的类中定义的。

public abstract class AbstractCourseFactory
{
    publicAbstractCourse createCourse(String scheduleType)
    {
        Course objCourse = this.getCourse(ScheduleType);        
        objCourse.createCourseMaterial();
        objCourse.createSchedule();
        return objCourse;
    }
    public abstract Course getCourse(String scheduleType);
}

所以每次我想要定义一个不同的Factory时,我只需要扩展这个基类,并实现工厂方法。然后客户端应该引用Factory基类(AbstractCourseFactory)。

所以现在我的Client类应该是这样的:

public class CourseProvider {
    AbstractCourseFactory factory;

    public CourseProvider(AbstractCourseFactory factory){
        this.factory = factory;
    }

    public Course startCourse(String scheduleType){
        Course course = factory.getCourse();
        course.start();
    }
}

但是Client类(CourseProvider)的实现似乎是"Simple Factory Pattern"

那么,实现工厂方法模式的最后一种方法是正确的吗?哪个最正确?

2 个答案:

答案 0 :(得分:0)

两者都是工厂模式。它们用于不同的场合。

当有一种类型时,使用第一种。 第二个提供了创建类系列的接口。

由于怀疑是第2次实施,我将尝试详细解释..

请注意以下类具有抽象方法getCourse

public abstract class AbstractCourseFactory
{
    publicAbstractCourse createCourse(String scheduleType)
    {
        Course objCourse = this.getCourse(ScheduleType);        
        objCourse.createCourseMaterial();
        objCourse.createSchedule();
        return objCourse;
    }
    public abstract Course getCourse(String scheduleType);
}

getCourse是课程对象的实际创建者。虽然createCourse只是对创建的对象进行了一些设置。

因此用户必须基于此创建多个工厂类并返回适当的具体Course对象。每个工厂类都将专门针对一个班级。

另请注意,通常,课程是一个界面或抽象类。 假设我们有两个课程系列.. GradedCourse和NonGradedCourses

interface Course {
   public String getCourseName();
}

public abstract class GradedCourse implements Course {
... 
}


GradedCourseA extends GradedCourse {
...
}

GradedCourseB extends GradedCourse {
...
}

public abstract class NonGradedCourse implements Course {
... 
}

NonGradedCourseA extends NonGradedCourse {
...
}

NonGradedCourseB extends NonGradedCourse {
...
}

AbsctractCourseFactory将扩展为创建两个类,如下所示

public CourseFactoryGradedCourses extends AbsctractCourseFactory {
   public Course getCourse(String scheduleType) {
      if (scheduleType.equals("A") {
         return new GradedCourseA ();
      } else if (scheduleType.equals("B") {
         return new GradedCourseB ();
      }
   }
}

public CourseFactoryNonGradedCourses extends AbsctractCourseFactory {
   public Course getCourse(String scheduleType) {
      if (scheduleType.equals("A") {
         return new NonGradedCourseA ();
      } else if (scheduleType.equals("B") {
         return new NonGradedCourseB ();
      }
   }
}

因此,CourseProvider将提供适当的具体工厂实现,以便创建该系列中的类。

...
 CourseProvider gradedCourseProvider= CourseProvider (new CourseFactoryGradedCourses ());
  // -->This creates concrete class GradedCourseA  from the family of graded courses..
  gradedProvider.startCourse("A");

 CourseProvider nonGradedCourseProvider =  CourseProvider (new CourseFactoryNonGradedCourses ());
     // -->This creates concrete class NonGradedCourseA  from the family of non graded courses..
  nonGradedCourseProvider.startCourse("A");

两者都是正确的工厂模式。 当需要创建不同的类族时,使用第二个。

模式在" Head First Design pattens"中得到了整齐的解释。书。

答案 1 :(得分:0)

您还可以实现类似这样的工厂方法:

public void DoSomething(Func<Stream> streamFactory)
{
    using(var stream = streamFactory())
    using(var reader = new StreamReader(..))
    {
        ...
    }
}

并称之为:

DoSomething(() => new FileStream(...));

注意:我意识到Stream的示例与问题中的示例无关,但问题是关于实现工厂方法的不同方法。