这是否使用了工厂设计模式?(Java)

3

我正在为一个OOAD课程的作业编写一个Java小程序,我遇到了一个问题,不太理解什么是正确的工厂设计模式以及如何在我的程序中实现它。

这是一个用于薪资计算的小程序。有一个名为Employee的基类和三个派生(子)类Hourly、Commissioned和Salaried。它们每个都有不同类型的支付数据类型。我只能在main类和整个程序中实例化一个对象。通过多态性,对象应该在类之间共享,并且我需要编写一个工厂方法来创建要分配给该对象的对象。

我有基类:

public class Employee {

protected Employee empFactory(int empType){
    if (empType == 1)
        return new Hourly();
    if (empType == 2)
        return new Commissioned();
    if (empType == 3)
        return new Salaried();
    else
        return null;
}

public static void main(String[] args) {
    // TODO code application logic here
}

还有三个派生类:

public class Commissioned extends Employee
public class Hourly extends Employee
public class Salaried extends Employee

我省略了一些数据类型和其他细节,我认为这应该足够提供信息。我拥有的工厂方法是“真正”的吗?我一直在阅读有关抽象和具体工厂方法以及具体产品等方面的内容,但仍感到困惑,不知道如何实现它。非常感谢任何帮助或指针!

3个回答

4
你差不多已经实现了一个工厂方法,但还不够完善。问题在于`empFactory`不是静态的,这意味着现在要使用它去创建一个员工需要先存在一个员工。将其改为静态的,你就迈出了进入工厂模式的第一步。
下一步是将`empFactory`方法的逻辑委托给一个单独的类,即工厂类。这将使得复杂性大大增加(而不会暴露给调用者),也是工厂模式的核心所在。

1
创建工厂的核心是创造更多的复杂性吗?(抱歉,我忍不住了) - Matti Virkkunen
2
创建工厂的核心在于允许更多复杂性,并将其封装在一个整洁的接口中。 - Louis Wasserman
@Snorkelfarsan 不需要。实际上,通常情况下,你理解了工厂模式的作用之后,会去查看Spring库。Spring基本上是工厂模式的标准化,涵盖了实际代码中几乎所有你需要的东西。(一些非常复杂的情况需要小的工厂方法来封装最棘手的决策。) - Donal Fellows
请注意,通常情况下,工厂方法在确定要创建的类时,会基于除了方法参数之外的更多信息做出决策(例如配置文件、系统属性)。 - Donal Fellows
@DonalFellows 那我应该看一下这个Spring库? - Snorkelfarsan
显示剩余3条评论

0

假设您了解泛型,您可以编写一个更好的工厂方法,允许您构造任何Employee子类的对象。

public static <T extends Employee> T empFactory(Class<T> clazz) {
    try {
        return clazz.newInstance();
    }
    catch(Exception e){
        return null;
    }
}

还有一个快速的例子:

public static void main(String[] args) {
    Employee emp = Employee.empFactory(Hourly.class);

    System.out.println("The salary is " + emp.getSalary());
}

这样做可以让你实例化任何继承自Employee的类,而无需每次添加新的派生类时更改工厂方法。它还使你摆脱了丑陋的(int,派生类)关联,因为你可以通过简单地指定所需的派生类来实例化对象。

如果需要访问特定于类的方法,还可以对实例进行强制转换:

Hourly hh = (Hourly) emp;

System.out.println("Salary is " + hh.getSalaryH());

注意:我的员工类(Employee class)有一个 getSalary() 方法,而我的小时工类(Hourly class)有一个 getSalaryH() 方法。

使用泛型可能是一个好主意,但这不是作业的一部分。我不知道老师是否会同意(并不是这个解决方案不好,但他似乎有一个非常具体的解决方案)。 - Snorkelfarsan

0
请查看下面的示例,其中描述了工厂模式。
interface vehicle {
    void start();
    void stop();
}
class car implements vehicle {
    public void start() {
        System.out.println("Start car");
    }
    public void stop() {
        System.out.println("Stop car");
    }
}
class bike implements vehicle {
    public void start() {
        System.out.println("Start bike");
    }
    public void stop() {
        System.out.println("Stop bike");
    }
}
class factory {
    public static vehicle getVehicle(int ch) { //(?)sould be interface type
        vehicle v = null;//local always inialize otherwise error
        //car c = new car();
        //bike b = new bike();
        if(ch == 1) {
            v = new car();
        } else {
            v = new bike();
        }
        return v;
    }
}
class factorymain {
    public static void main(String[] args) {
        vehicle v;
        v = factory.getVehicle(Integer.parseInt(args[0]));
        v.start();
        v.stop();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接