Java 问题中的工厂方法模式示例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10567182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Factory Method Pattern Example in Java troubles
提问by Amir Afghani
I'm trying to create a really simple Factory Method design pattern example in Java. I don't really know Java, I am new to programming in general but I need to come up with a a basic FactoryMethod example implemented in java. The following is what I came up with. There are quite a few errors I'm sure, I'm missing some constructors apparently and I get confused with abstract classes and interfaces. Could you point out my mistakes and correct my code along with an explanation please? Thank you in advance for your time and help.
我正在尝试用 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
}
}
回答by Amir Afghani
In brief there are several issues in your version that were corrected below:
简而言之,您的版本中有几个问题已在下面更正:
createPerson
method is useless.- The way you invoke the factory method is wrong.
- You use
==
instead of.equals
in your factory method.
createPerson
方法没用。- 你调用工厂方法的方式是错误的。
- 您在工厂方法中使用
==
而不是.equals
。
I've enhanced your Person class to add a member field that is shared by the Male and Female class, to demonstrate how sharing a common abstract constructor could be used.
我已经增强了您的 Person 类,以添加由男性和女性类共享的成员字段,以演示如何使用共享公共抽象构造函数。
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"));
}
}
回答by Paul Sullivan
Should be:
应该:
public class Test
{
public static void main(String[] args)
{
Person y= PersonFactory.makePerson("male");
Person z= PersonFactory.makePerson("female");
}
}
The reason it is
原因是
PersonFactory.makePerson("male")
is because you have a static method makePerson (which means you do not have to 'new' a class to call the method as it is not an instance method) i.e. a static variable in a class is available to all instances of a class. A static method is called TheClassItIsDefinedIn.TheMethodSignature
是因为您有一个静态方法 makePerson(这意味着您不必“新建”一个类来调用该方法,因为它不是一个实例方法)即类中的静态变量可用于类的所有实例。静态方法称为 TheClassItIsDefinedIn.TheMethodSignature
Additionally:
此外:
public abstract class Person
{
public void createPerson(){ }
}
should really be an interface as you have no functional code that is shared between derived types (well not shown here any way) and here is a laymans explanation of abstract and interface:
应该真的是一个接口,因为您没有在派生类型之间共享的功能代码(这里没有以任何方式显示),这里是抽象和接口的外行解释:
interface: A contract that states 'I have method blah and blah2 so any class implementing me must have a method of that name and signature (and it can have whatever code it likes in there as long as it matches the return type etc)'
接口:一个合同,声明“我有方法 blah 和 blah2,因此任何实现我的类都必须有一个具有该名称和签名的方法(并且它可以在其中包含它喜欢的任何代码,只要它与返回类型等匹配)”
abstract: an abstract class can have method signatures just like an interface BUT it also would usually have concrete implementations that are generic amongst all deriving types
抽象:抽象类可以像接口一样具有方法签名,但它通常也具有在所有派生类型中通用的具体实现
回答by maress
I would recommend you get a grip in java programming before starting to apply design patterns. Design patterns normally require OO principles, and as such would not make any much sense if you lack good programming practices.
我建议您在开始应用设计模式之前先掌握 Java 编程。设计模式通常需要 OO 原则,因此如果您缺乏良好的编程实践,则没有任何意义。
Nonetheless, the definition of your Factory method looks right in the context of the meaning but not in usability. The Factory Method needs to create an object, and hence return a reference to the created object. Furthermore, the created object is usually different from the class that implements the Factory Method pattern, since it is envisaged that the created instance is to be used by object, in this case Person.
尽管如此,工厂方法的定义在含义的上下文中看起来是正确的,但在可用性方面却不是。工厂方法需要创建一个对象,因此返回对创建对象的引用。此外,创建的对象通常与实现工厂方法模式的类不同,因为设想创建的实例将由对象使用,在这种情况下为 Person。
So here is an abstract example of probably how you may use the factory pattern.
因此,这里有一个抽象示例,说明您可能如何使用工厂模式。
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();
}
}
回答by JAN
Complete example based on @maress' code :
基于@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);
}
}
回答by Ravindra babu
Refactored the above code.
重构了上面的代码。
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");
}
}
Key notes:
要点:
Created the objects (
Male
andFemale
) once in static block.Not creating new object every time. Creation happens once. Every
makePerson
calls return existing object from the factory.Removed
createPerson
method
在静态块中创建对象(
Male
和Female
)一次。不是每次都创建新对象。创造发生一次。每个
makePerson
调用都从工厂返回现有对象。删除的
createPerson
方法
Have a look at related post @
看看相关帖子@