5

我正在尝试用 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
    }
}
4

5 回答 5

8

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

  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"));
    }
}
于 2012-05-12T20:48:28.063 回答
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(){ }
}

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

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

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

于 2012-05-12T20:36:55.550 回答
2

我建议您在开始应用设计模式之前掌握 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();
    }
  }
于 2012-05-12T21:03:18.673 回答
1

基于@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);
    }
}
于 2015-09-26T14:40:18.783 回答
0

重构了上面的代码。

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. 在静态块中创建对象 (Male和) 一次。Female

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

  3. 删除的createPerson方法

看看相关的帖子@

工厂模式。什么时候使用工厂方法?

于 2018-07-19T12:55:41.027 回答