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的实现与头一本书中描述的“简单工厂模式”一致