【问题标题】:Factory Method Pattern Example in Java troublesJava麻烦中的工厂方法模式示例
【发布时间】:2012-05-12 20:31:50
【问题描述】:

我正在尝试用 Java 创建一个非常简单的工厂方法设计模式示例。我真的不太懂 Java,一般来说我是编程新手,但我需要想出一个用 java 实现的基本 FactoryMethod 示例。以下是我想出的。我敢肯定有很多错误,我显然缺少一些构造函数,并且我对抽象类和接口感到困惑。您能否指出我的错误并纠正我的代码以及解释?提前感谢您的时间和帮助。

public abstract class Person 
{   
    public void createPerson(){ }
}

public class Male extends Person 
{   
    @Override
    public void createPerson() 
    {
        System.out.print("a man has been created");
    }
}

public class Female extends Person 
{   
    @Override
    public void createPerson() 
    {
        System.out.print("a woman has been created");
    }
}

public class PersonFactory
{
     public static Person makePerson(String x) // I have no Person constructor in
     {                                         // the actual abstract person class so 
         if(x=="male")                         // is this valid here?
         { 
             Male man=new Male();
             return man;
          }
          else
         {
             Female woman=new Female();
             return woman;
         }
     }
}


public class Test 
{
    public static void main(String[] args)
    {
       Person y= new Person(makePerson("male"));   // definitely doing smth wrong here
       Person z= new Person(makePerson("female")); // yup, here as well
    }
}

【问题讨论】:

  • 类有一个隐式的、无参数的new,除非你定义了一个带参数的构造函数。
  • "...请更正我的代码并附上解释?"这不是家庭作业修正服务。请向我们展示任何编译错误并描述任何行为问题。这里的努力应该是你的
  • @Hovercraft Full Of Eels 这不是作业。我正在为考试而学习,我需要学习 FactoryMethod 设计模式。互联网上到处都是 Java 示例,我觉得这些示例过于复杂。我不是想“作弊”我想了解这就是为什么我向您提供了我编写但不起作用的代码。
  • 这不是作弊的问题,而是你的问题,你真的不应该试图让别人难以帮助,你应该更加努力。你应该发布你的错误信息,你应该努力尝试调试你的代码并展示这个努力的结果。如果您寻求免费建议,这样做是正确的。

标签: java design-patterns factory


【解决方案1】:

简而言之,您的版本中有几个问题已在下面得到纠正:

  1. createPerson 方法没用。
  2. 你调用工厂方法的方式不对。
  3. 您在工厂方法中使用== 而不是.equals

我已经增强了您的 Person 类,以添加一个由 Male 和 Female 类共享的成员字段,以演示如何使用共享一个通用抽象构造函数。

public abstract class Person {   
    protected final String name;
    public Person(String name) { 
        this.name = name;
    }
}

public class Male extends Person {
    public Male(String name) { 
        super(name);
    }
}

public class Female extends Person {
    public Female(String name) { 
        super(name);
    }
}

public class PersonFactory
{
     public static Person makePerson(String gender, String name) 
     {
         if(gender.equals("male"))                       
         { 
             Male man=new Male(name);
             return man;
         }
         else
         {
             Female woman=new Female(name);
             return woman;
         }
     }
}

public class Test 
{
    public static void main(String[] args)
    {
       Person y= PersonFactory.makePerson("male", "bob"));
       Person z= new PersonFactory.makePerson("female", "janet"));
    }
}

【讨论】:

  • 哇,谢谢阿米尔,这就是我想要的。我现在将查看您的代码并尝试了解正在发生的事情.. 还要感谢 Paul 和 Dave! :)
  • 一般意义上,这种实现被称为简单工厂模式,意思是它不是设计模式,而是面向对象的。我将很快给出一个示例作为答案。
【解决方案2】:

应该是:

public class Test 
{
    public static void main(String[] args)
    {
       Person y= PersonFactory.makePerson("male");  
       Person z= PersonFactory.makePerson("female");
    }
}

原因

PersonFactory.makePerson("male")

是因为您有一个静态方法 makePerson(这意味着您不必“新建”一个类来调用该方法,因为它不是实例方法),即类中的静态变量可用于所有实例班级。静态方法称为 TheClassItIsDefinedIn.TheMethodSignature

另外:

public abstract class Person 
{   
    public void createPerson(){ }
}

应该真的是一个接口,因为你没有在派生类型之间共享的功能代码(这里没有以任何方式显示),这里是抽象和接口的外行解释:

interface:声明“我有方法 blah 和 blah2 的合同,因此任何实现我的类都必须有一个具有该名称和签名的方法(并且它可以在其中包含它喜欢的任何代码,只要它与返回类型匹配等) )'

抽象:抽象类可以像接口一样具有方法签名,但它通常也具有在所有派生类型中通用的具体实现

【讨论】:

  • hmmm.. 为什么我运行测试时屏幕上没有出现“一个男人被创造了一个女人被创造了”?我的 makePerson 函数不是要求创建男性和女性对象吗?
  • 在调试环境中添加断点进行测试(但应该)
  • @user1073400 因为没有任何东西调用createPerson
【解决方案3】:

我建议您在开始应用设计模式之前掌握 Java 编程。 设计模式通常需要 OO 原则,因此如果您缺乏良好的编程实践,这将没有多大意义。

尽管如此,您的工厂方法的定义在含义的上下文中看起来是正确的,但在可用性方面却不是。工厂方法需要创建一个对象,因此返回对创建对象的引用。此外,创建的对象通常与实现工厂方法模式的类不同,因为设想创建的实例将由对象使用,在本例中为 Person。

所以这里有一个抽象的例子,说明你可能如何使用工厂模式。

  public abstract class Student {
  }

  public class PrimarySchoolStudent extends Student {
  }

  public class HighSchoolStudent extends Student {
  }

  public abstract class ClassRoom {

    private List<Student> students;

    void enrollStudent(String studentId) {
      Student student = newStudent();
      students.add(student);
    }

    abstract Student newStudent();
  }

  public class HighSchoolClassRoom extends ClassRoom {

    @Override
    Student newStudent() {
      return new HighSchoolStudent();
    }
  }

  public class PrimarySchoolClassRoom extends ClassRoom {

    @Override
    Student newStudent() {
      return new PrimarySchoolStudent();
    }
  }

【讨论】:

  • 非常感谢您花时间为我提供此代码示例。它似乎比我的更复杂,但我也会看看它并尝试了解正在发生的事情。我更熟悉在 C++ 中编程和创建类,但在 Java 中不熟悉..
  • 这将是工厂方法的最佳示例!
  • 抽象方法newStudent实际上是一个工厂方法,使得这个例子有别于[简单工厂模式],它使用switch或if-else语句来实现。
【解决方案4】:

基于@maress'代码的完整示例:

import java.util.ArrayList;
import java.util.List;

abstract class Student {
    private int StudentID;

    public Student() {
    }

    public Student(int _studentId) {
        this.StudentID = _studentId;
    }

}

class PrimarySchoolStudent extends Student {

    public PrimarySchoolStudent() {
    }

    public PrimarySchoolStudent(int _studentId) {
        super(_studentId);
    }
}

class HighSchoolStudent extends Student {

    public HighSchoolStudent() {
    }

    public HighSchoolStudent(int _studentId) {
        super(_studentId);
    }
}

abstract class ClassRoom {
    private List<Student> students;

    public void enrollStudent(int studentId) {
        if (students == null)
        {
            students = new ArrayList<Student>();
        }
        Student student = newStudent(studentId);
        students.add(student);
    }

    abstract Student newStudent(int studentId);
}

class HighSchoolClassRoom extends ClassRoom {

    @Override
    Student newStudent(int studentId) {
        return new HighSchoolStudent(studentId);
    }
}

class PrimarySchoolClassRoom extends ClassRoom {

    @Override
    Student newStudent(int studentId) {
        return new PrimarySchoolStudent(studentId);
    }
}

public class RunCode {
    public static void main(String[] args) {

        ClassRoom cr_highSchool = new HighSchoolClassRoom();
        cr_highSchool.enrollStudent(1234);
        cr_highSchool.enrollStudent(5678);
        cr_highSchool.enrollStudent(1938);
        cr_highSchool.enrollStudent(7465);
    }
}

【讨论】:

    【解决方案5】:

    重构了上面的代码。

    import java.util.HashMap;
    
    class Person  {   
       String name;
    
       public Person(String name){
            this.name = name;
       }
       public void setName(String name){
            this.name = name;
       }
       public String getName(){
            return name; 
       }
    }
    
    class Male extends Person {   
    
        public Male(String name) {
            super(name);
            System.out.println("a man has been created with name:"+name);
        }
    }
    
    class Female extends Person{   
    
        public Female(String name) {
            super(name);
            System.out.print("a woman has been created with name:"+name);
        }
    }
    
    class PersonFactory {
         private static HashMap<String,Person> factory = new HashMap<String,Person>();
         static {
            factory.put("male", new Male ("Trump"));
            factory.put("female", new Female ("Theresa May"));
    
         }
         public static Person makePerson(String type) {                                        
             return factory.get(type);                     
         }
    }
    
    
    public class Test {
        public static void main(String[] args){
           Person y= PersonFactory.makePerson("male");  
           Person z= PersonFactory.makePerson("female");
        }
    }
    

    重点说明:

    1. 在静态块中创建了一次对象(MaleFemale)。

    2. 不是每次都创建新对象。创造发生一次。每个makePerson 调用都从工厂返回现有对象。

    3. 删除了createPerson方法

    查看相关帖子@

    Factory Pattern. When to use factory methods?

    【讨论】:

      猜你喜欢
      • 2017-10-02
      • 2011-01-24
      • 2018-06-30
      • 1970-01-01
      • 1970-01-01
      • 2014-08-04
      • 2019-08-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多