5

Java で非常に単純な Factory Method 設計パターンの例を作成しようとしています。私は 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 の原則が必要であり、優れたプログラミング手法がなければ意味がありません。

それにもかかわらず、Factory メソッドの定義は、意味のコンテキストでは正しく見えますが、使いやすさでは正しくありません。Factory メソッドはオブジェクトを作成する必要があるため、作成されたオブジェクトへの参照を返します。さらに、作成されたオブジェクトは通常、Factory Method パターンを実装するクラスとは異なります。これは、作成されたインスタンスがオブジェクト (この場合は 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) を static ブロックに一度作成しました。

  2. 毎回新しいオブジェクトを作成するわけではありません。作成は一度だけ行われます。すべてmakePersonの呼び出しは、ファクトリから既存のオブジェクトを返します。

  3. 削除されたcreatePersonメソッド

関連記事@をご覧ください

工場のパターン。ファクトリ メソッドを使用する場合

于 2018-07-19T12:55:41.027 に答える