Java 什么';这两者之间的区别是什么;工厂法“;及;使用“新建”创建实例;?

Java 什么';这两者之间的区别是什么;工厂法“;及;使用“新建”创建实例;?,java,design-patterns,Java,Design Patterns,我的工厂方法代码如下: public class DBFactory { protected DBFactory() {} protected static DataBase createDB() { return null; } } public class MySQLFactory extends DBFactory{ private MySQLFactory() {} public static DataBase createDB() {

我的工厂方法代码如下:

public class DBFactory {
    protected DBFactory() {}
    protected static DataBase createDB() { return null; }
}

public class MySQLFactory extends DBFactory{
    private MySQLFactory() {}

    public static DataBase createDB() {
        return new MySQL();
    }
}

public class SQLServerFactory extends DBFactory{
    private SQLServerFactory() {}

    public static DataBase createDB() {
        return new SQLServer();
    }
}    

public class Test {
    public static void main(String[] args) {
        DataBase db = SQLServerFactory.createDB();
        db.connect();
    }
}
package factorymethod;

import db.DataBase;

public class Test {
    public static void main(String[] args) {
        DataBase db = new MySQL();
        db.connect();
    }
}
我发现它与下面的客户代码没有区别:

public class DBFactory {
    protected DBFactory() {}
    protected static DataBase createDB() { return null; }
}

public class MySQLFactory extends DBFactory{
    private MySQLFactory() {}

    public static DataBase createDB() {
        return new MySQL();
    }
}

public class SQLServerFactory extends DBFactory{
    private SQLServerFactory() {}

    public static DataBase createDB() {
        return new SQLServer();
    }
}    

public class Test {
    public static void main(String[] args) {
        DataBase db = SQLServerFactory.createDB();
        db.connect();
    }
}
package factorymethod;

import db.DataBase;

public class Test {
    public static void main(String[] args) {
        DataBase db = new MySQL();
        db.connect();
    }
}

问题是,为什么我必须使用工厂方法?我认为它会变得更加冗长…

工厂方法是一种软件设计模式,它可以帮助您实现类的类分类法之类的族的实例化


如果您只实例化一个类,并且不希望将来更改代码以适应新的类,那么您可以安全地避免应用该模式,因为它确实是毫无意义的冗长/不必要的。

当您需要虚拟构造函数时,您使用工厂方法:在运行时使用不同的类型

调用
new
只能创建一种类型

工厂可以创建一系列类型,只要它们有一个公共接口或父类,具体取决于传入的参数。

如果将类设置为非静态,并且工厂方法为非静态,则更有意义,因为您可以在运行时向客户机提供抽象工厂:

public interface DBFactory { // Note: interface, not abstract class
    public DataBase createDB();
}

public class MySQLFactory implements DBFactory {
    public DataBase createDB() {
        return new MySQL();
    }
}

public class SQLServerFactory extends DBFactory{
    public DataBase createDB() {
        return new SQLServer();
    }
} 
然后


您可以使用工厂方法来实现单例设计模式

例如,假设在应用程序生命周期的任何时候都不需要有多个MySQL()对象。您可以使用工厂方法来确保创建的MySQL()对象不会超过一个。考虑下面的(pUEDEOESQ)代码:

有了这段代码,您几乎可以保证不会创建该对象的多个实例。这有助于在创建新对象时节省资源,这可能会很昂贵


编辑:我确实认为我超出了你最初问题的范围

工厂方法模式允许您指定特定的具体对象,而无需接触基类。这促进了打开/关闭原则依赖倒置原则。后者表示:“从不依赖于具体类,而是使低级元素(具体对象)依赖于高级元素(抽象元素)”

事实上,假设您有三种数据库。如果没有工厂模式(或抽象工厂模式),您将得到以下代码:

protected DBFactory(String database) {
   if (database.equals("MySQL")) {
       this.database = new MySql();
   } else if (database.equals("PostgreSQL") {
       this.database = new PostgreSQL();
   }
   else{
       this.database = new Oracle();
   }
} 
Factory template方法允许您通过继承指定此子类型。 它在实例化时是固定的,并且不能在运行时更改,这与抽象工厂模式相反

因此,如果没有工厂,只要您想添加一种新的数据库,就必须违反开放/关闭原则,因此可能会破坏基类的现有工作功能

无论如何,在你的特定情况下,使用它是没有意义的。
为什么?因为当工厂由程序(程序的核心包含业务逻辑)使用时,它特别有用,而不是由“main”方法或任何其他流程使用,这些流程只是聚合、馈送和操作这些逻辑组件。

@user984444和@Mik378抓住要点。 工厂方法可以: 1.保证实例为单例。 2.使用不同的方法/参数生成不同的具体实例。您不必检查子类/实现

更好地理解工厂方法模式是,假设您在工厂中,您不知道生产过程,但是您可以得到您想要的产品。让我们看一看。 MealFactory=new ChineseMealFactory(); factory.prepareDessert()将返回中文版本。
就是这样。

谁说你必须使用工厂方法?你不必这么做。在这种情况下,这确实没有多大意义。如果您只有DBFactory,并且factory方法使用一些运行时信息(如配置文件或系统属性)返回一个数据库实现,那么这是有意义的。您好@JBNizet,您的意思是我可以使用“简单工厂”对吗?你能给我一个我应该使用“工厂方法”的例子吗?你好,但是你的代码和在客户端使用new有什么区别吗?@Alexis:区别是这样的:1)你有一个属性文件,它指定了在应用程序中使用哪个工厂,例如:
dbFactory=SQLServerFactory
2)您的应用程序在启动时读取属性文件并执行如下操作:
factory=Class.forName(dbFactory)。3) 您的客户端代码执行此操作
数据库db=factory.createDB()
。现在,您的应用程序是独立于数据库的,您不必更改客户端代码或工厂创建代码来添加新数据库。当然,您也可以对一组
if
语句执行相同的操作。