Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 工厂方法模式的不同实现方式_Java_C#_Oop_Design Patterns_Factory Pattern - Fatal编程技术网

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

Java 工厂方法模式的不同实现方式,java,c#,oop,design-patterns,factory-pattern,Java,C#,Oop,Design Patterns,Factory Pattern,我看到了一个工厂方法模式示例,其中客户机类被定义为抽象类,并包括一个抽象方法(即工厂方法),如下所示: abstract createCourse(String scheduleType); public class CourseProvider { AbstractCourseFactory factory; public CourseProvider(AbstractCourseFactory factory){ this.factory = factor

我看到了一个
工厂方法模式
示例,其中客户机类被定义为抽象类,并包括一个抽象方法(即工厂方法),如下所示:

abstract createCourse(String scheduleType);
public class CourseProvider {
    AbstractCourseFactory factory;

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

    public Course startCourse(String scheduleType){
        Course course = factory.getCourse();
        course.start();
    }
}
public void DoSomething(Func<Stream> streamFactory)
{
    using(var stream = streamFactory())
    using(var reader = new StreamReader(..))
    {
        ...
    }
}
因此,我需要扩展抽象客户机类并实现
createCourse
方法。下面是一个代表客户机的示例:

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

        return course;
    }

    abstract createCourse(String scheduleType); 
}
每次我想使用一个不同的工厂,我必须扩展它

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

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);
}
所以每次我想定义一个不同的工厂,我只需要扩展这个基类,并实现工厂方法。然后客户端应该有一个对工厂基类(AbstractCourseFactory)的引用

现在我的客户机类应该如下所示:

abstract createCourse(String scheduleType);
public class CourseProvider {
    AbstractCourseFactory factory;

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

    public Course startCourse(String scheduleType){
        Course course = factory.getCourse();
        course.start();
    }
}
public void DoSomething(Func<Stream> streamFactory)
{
    using(var stream = streamFactory())
    using(var reader = new StreamReader(..))
    {
        ...
    }
}
但是客户端类(CourseProvider)的这种实现似乎是一种
的“简单工厂模式”


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

都是出厂模式。它们用于不同的场合

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

由于疑点在于第二次实施,我将尝试详细解释

请注意下面的类有一个抽象方法
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只是对创建的对象进行一些设置

因此,用户必须基于此创建多个工厂类,并返回相应的具体课程对象。每个Factory类将特定于一系列类

另外请注意,通常情况下,课程是一个接口或抽象类。 假设我们有两门课。。分级课程和非分级课程

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 {
...
}
AbscactCourseFactory将被扩展以创建两个类,如下所示

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");
两者都是正确的工厂模式。 第二种方法是在需要创建不同的类族时使用

...
 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");

这些模式在“头先设计模式”一书中有很好的解释

您还可以实现类似以下内容的工厂方法:

abstract createCourse(String scheduleType);
public class CourseProvider {
    AbstractCourseFactory factory;

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

    public Course startCourse(String scheduleType){
        Course course = factory.getCourse();
        course.start();
    }
}
public void DoSomething(Func<Stream> streamFactory)
{
    using(var stream = streamFactory())
    using(var reader = new StreamReader(..))
    {
        ...
    }
}

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

第二个示例似乎是一个,而不仅仅是工厂方法。此外,抽象工厂的第一条规则是“尽量不要使用抽象工厂”。创造性方法中的
scheduleType
参数表示工厂的潜在误用。工厂的具体类型应该决定创建哪种类型的对象,而不是传递给创建方法的参数。谢谢@guillaume31,但本文说它是工厂方法模式,而不是抽象工厂模式。我错了吗?你没有错,这篇文章是(或者至少是不准确的):)也许:)但是,据我所知,这两种模式非常相似,唯一的区别是抽象模式强调了家庭分组的方面。谢谢!我从Head-first设计模式中选取了第一个示例,而第二个示例取自。在后者中,Creator calss的实现与头一本书中描述的“简单工厂模式”一致