问题描述
什么是工厂,为什么要使用一个?
推荐答案
您是否熟悉 jdbc ?这是全部(抽象)工厂.这是一个很好的现实世界例子.
// Factory method. Loads the driver by given classname. It actually returns a // concrete Class<Driver>. However, we don't need it here, so we just ignore it. // It can be any driver class name. The MySQL one here is just an example. // Under the covers, it will do DriverManager.registerDriver(new Driver()). Class.forName("com.mysql.jdbc.Driver"); // Abstract factory. This lets the driver return a concrete connection for the // given URL. You can just declare it against java.sql.Connection interface. // Under the covers, the DriverManager will find the MySQL driver by URL and call // driver.connect() which in turn will return new ConnectionImpl(). Connection connection = DriverManager.getConnection(url); // Abstract factory. This lets the driver return a concrete statement from the // connection. You can just declare it against java.sql.Statement interface. // Under the covers, the MySQL ConnectionImpl will return new StatementImpl(). Statement statement = connection.createStatement(); // Abstract factory. This lets the driver return a concrete result set from the // statement. You can just declare it against java.sql.ResultSet interface. // Under the covers, the MySQL StatementImpl will return new ResultSetImpl(). ResultSet resultSet = statement.executeQuery(sql);
您不需要在代码中具有JDBC驱动程序特定import的单行.您不需要做import com.mysql.jdbc.ConnectionImpl或其他事情.您只需要声明一切反对java.sql.*即可.您不需要自己做connection = new ConnectionImpl();.您只需要从抽象工厂作为标准API的一部分获得它.
如果将JDBC驱动程序类名称称为一个可以外部配置(例如属性文件)并编写兼容SQL查询的变量,那么您永远都不需要重写,重新编译,重建,重建和重新分发您的Java应用程序世界所知道的数据库供应商和/或JDBC驱动程序.您只需要将所需的JDBC驱动程序JAR文件放在运行时类路径中,并通过某些(属性)文件提供配置,而无需在要切换DB或在其他DB上重复使用该应用程序时更改Java代码的任何行.
这是界面和抽象工厂的力量.
另一个已知的现实世界示例是Java EE.用" java ee"和" jdbc驱动程序"用" java ee application server"替换" jdbc"(wildfly,tomee,玻璃鱼,自由等).
另请参见:
其他推荐答案
在您需要在运行时创建对象的多个实例的情况下,出厂设计模式是理想的选择.而不是明确创建每个实例,您可以初始化许多实例.此外,您可以封装可以多次重复使用的复杂创建代码.
示例:
public class Person { int ID; String gender; public Person(int ID,String gender){ this.ID=ID; this.gender=gender; } public int getID() { return ID; } public String getGender() { return gender; } } public class PersonFactory{ public static Person createMale(int id){ return new Person(id,"M"); } public static Person createFemale(int id){ return new Person(id,"F"); } } public class factorytest{ public static void main(String[]args){ Person[] pList= new Person[100]; for(int x=0;x<100;x++){ pList[x]=PersonFactory.createMale(x); } } }
在此示例中,我们封装了性别初始化参数的详细信息,可以简单地向人物征求创建或创建人物对象.
其他推荐答案
简单地说, Factory 是一种OO设计模式,涉及创建对象而不指定要创建的确切对象.
使用它的一个很好的理由定义了 in wikipedia :
对象的创建通常不需要复杂的过程 适合包含在组成对象中.对象的 创建可能会导致代码重复,可能需要 编写对象无法访问的信息可能无法提供 足够的抽象水平,或者可能不属于 编写对象的问题.工厂方法设计模式手柄 这些问题通过定义创建对象的单独方法, 然后,哪些子类可以覆盖以指定的类型 将创建的产品.
问题描述
What is a factory and why would I want to use one?
推荐答案
Are you familiar with JDBC? It's one and all (abstract) factory. It's a good real world example.
// Factory method. Loads the driver by given classname. It actually returns a // concrete Class<Driver>. However, we don't need it here, so we just ignore it. // It can be any driver class name. The MySQL one here is just an example. // Under the covers, it will do DriverManager.registerDriver(new Driver()). Class.forName("com.mysql.jdbc.Driver"); // Abstract factory. This lets the driver return a concrete connection for the // given URL. You can just declare it against java.sql.Connection interface. // Under the covers, the DriverManager will find the MySQL driver by URL and call // driver.connect() which in turn will return new ConnectionImpl(). Connection connection = DriverManager.getConnection(url); // Abstract factory. This lets the driver return a concrete statement from the // connection. You can just declare it against java.sql.Statement interface. // Under the covers, the MySQL ConnectionImpl will return new StatementImpl(). Statement statement = connection.createStatement(); // Abstract factory. This lets the driver return a concrete result set from the // statement. You can just declare it against java.sql.ResultSet interface. // Under the covers, the MySQL StatementImpl will return new ResultSetImpl(). ResultSet resultSet = statement.executeQuery(sql);
You do not need to have a single line of JDBC driver specific import in your code. You do not need to do import com.mysql.jdbc.ConnectionImpl or something. You just have to declare everything against java.sql.*. You do not need to do connection = new ConnectionImpl(); yourself. You just have to get it from an abstract factory as part of a standard API.
If you make the JDBC driver class name a variable which can be configured externally (e.g. properties file) and write ANSI compatible SQL queries, then you do not ever need to rewrite, recompile, rebuild and redistribute your Java application for every single database vendor and/or JDBC driver which the world is aware of. You just have to drop the desired JDBC driver JAR file in the runtime classpath and provide configuration by some (properties) file without the need to change any line of Java code whenever you want to switch of DB or reuse the app on a different DB.
That's the power of interfaces and abstract factories.
Another known real world example is Java EE. Substitute "JDBC" with "Java EE" and "JDBC driver" with "Java EE application server" (WildFly, TomEE, GlassFish, Liberty, etc).
See also:
- How exactly do Class#forName() and DriverManager#getConnection() work?
- What exactly is Java EE?
- Wikipedia: Factory method pattern
- Wikipedia: Abstract factory pattern
其他推荐答案
The Factory design pattern is ideal in circumstances when you need to create multiple instances of an object at run time. Rather than explicitly creating each instance you can initialize many instances. Additionally, you can encapsulate complex creation code that can be reused multiple times.
Example:
public class Person { int ID; String gender; public Person(int ID,String gender){ this.ID=ID; this.gender=gender; } public int getID() { return ID; } public String getGender() { return gender; } } public class PersonFactory{ public static Person createMale(int id){ return new Person(id,"M"); } public static Person createFemale(int id){ return new Person(id,"F"); } } public class factorytest{ public static void main(String[]args){ Person[] pList= new Person[100]; for(int x=0;x<100;x++){ pList[x]=PersonFactory.createMale(x); } } }
In this example we encapsulate the details of the gender initialization parameter and can simply ask the PersonFactory to createMale or createFemale Person objects.
其他推荐答案
In simple terms, Factory is an OO design pattern that deals with creating objects without specifying the exact class of object that is to be created.
A good reason to use it is well defined in wikipedia:
The creation of an object often requires complex processes not appropriate to include within a composing object. The object's creation may lead to a significant duplication of code, may require information not accessible to the composing object, may not provide a sufficient level of abstraction, or may otherwise not be part of the composing object's concerns. The factory method design pattern handles these problems by defining a separate method for creating the objects, which subclasses can then override to specify the derived type of product that will be created.