我正在尝试学习创作设计模式,我想我现在理解工厂方法模式。 但是在转向抽象工厂模式时,我找不到它的用途。我知道我错过了这个,但不知道在哪里。
在抽象工厂模式中,我们将有一个抽象工厂,具体工厂将返回实例。假设我们正在处理汽车的创建。我们将有一个抽象工厂,如
hello-world
我们的具体工厂将是
public interface CarFactory{
public Car getCar();
}
在用户类中,我们将像
一样使用它public class AudiFactory{
public Car getCar(){
return new Audi();
}
}
public class VolvoFactory{
public Car getCar(){
return new Volvo();
}
}
我认为我们也可以使用Factory Pattern构建相同的功能
CarFactory factory = new AudiFactory();
Car carAudi = factory.getCar();
factory = new VolvoFactory();
Car carVolvo = factory.getCar();
在用户类中我们可以
public class CarFactory{
public Car getCar(String make){
if("Audi".equals(make))
return new Audi();
else if("Volvo".equals(make))
return new Volvo();
}
}
如果我的理解是正确的(如果错误请纠正我),为什么我们需要另一种设计模式?
答案 0 :(得分:4)
对于您的示例,是的,您是正确的工厂模式可以取代抽象工厂模式。
抽象工厂在您需要创建同一家族的不同产品而无需了解家族(沃尔沃或奥迪)时才有意义。
interface Car {}
interface Engine {}
interface Gear {}
interface ICarFactory {
Car createCar();
Engine createEngine();
Gear createGear();
}
class AudiCar implements Car {}
class AudiEngine implements Engine {}
class AudiGear implements Gear {}
class AudiFactory implements ICarFactory {
public Car createCar() { return new AudiCar(); }
public Engine createEngine() { return new AudiEngine(); }
public Gear createGear() { return new AudiGear(); }
}
我相信你可以为沃尔沃成像。
现在假设我们有一个构建Car
的类,这并不关心它是奥迪还是沃尔沃。
class CarBuilder {
public static Car buildCar(ICarFactory factory) {
Car car = factory.createCar();
car.setEngine(factory.createEngine());
car.setGear(factory.createGear());
return car;
}
}
现在我们的构建器类可以在不知道使构建器类符合Open/Closed Principle的实际品牌的情况下工作。如果将来有第三个品牌,我们的构建器类仍然可以构建该车而无需更改单行代码。由于抽象的工厂,它向扩展开放但关闭以改变。
答案 1 :(得分:2)
在你的例子中:
工厂方法模式是创建汽车的模式(隐藏汽车创建的实现)
抽象工厂模式是创建汽车工厂的模式(汽车工厂创建,非汽车创造,专注于工厂创建)
所以你可以这么认为:抽象工厂模式是一种创建工厂工厂的模式
这两种模式用于不同目的。
抽象工厂模式(使用Interface / Abstract实现)+ IoC pattern - >帮助您确定运行时使用的汽车工厂类型 - 不在编译时(工厂方法模式不符合此要求)
答案 2 :(得分:0)
想想java.sql.Connection对象 对我来说,它是一个抽象的工厂
它为您生成Statement,CallableStatement等
在内部,它可以是OracleStatement或MySQLStatement
您的客户端代码是干净的,它并不关心它如何在内部将套接字连接到数据库服务器
另见 Design Patterns: Abstract Factory vs Factory Method
关于您的原始代码
想想现实世界,通用汽车不是用丰田制造的,而是工厂制造的#34;或一些通用汽车工厂:)
你所取得的成就是摆脱if-else 考虑学习整个设计模式列表,简单地删除你的代码中的if-else
如果Sun有一组有限的数据库需要处理,他们可以写一些if else
事实是
1)SQL驱动程序不是由sun编写的 2)使用这种模式你可以注射"代码中的任何驱动程序,无需担心它是如何工作的,只需依赖接口
要求客户通过"奥迪"每次通话都是不合理的
答案 3 :(得分:0)
你已经很好地理解了Factory模式的使用:工厂允许tou创建在编译时类型未知的对象(只是接口的子类,是corse)。现在,迈出更远的一步:
现在你有一个CarFactory
来创建Car
个对象。但是,当您在计划中同时需要多个工厂时,您将如何管理?
当抽象工厂进来时:抽象工厂是工厂工厂,它允许您在编译时创建类型未知的工厂:那么,你
public interface AbstractCarFactory
{
public CarFactory getCarFactory(String area);
}
...您将能够实施EuropeanCarFactory,AmericanCarFactory等。
另一个抽象工厂有用的例子是当你的构造函数中有一些带有参数的工厂类时:
public CarFactory
{
public CarFactory(boolean cheatingMotor) {...}
}
通过动态实例化(Class.forName("CarFactory").newInstance()
)很难创建一个CarFactory对象,因此向上一级分解是有用的:抽象工厂决定如何实例化CarFactory:
public interface AbstractCarFactory
{
public CarFactory(boolean cheatingMotor);
}
public class MyAbstractCarFactory implements AbstractFactory
{
public CarFactory(boolean cheatingMotor)
{
return new CarFactory(true);
}
}
注意:在常见的应用程序中,抽象工厂模式足以正确地参数化所有应用程序的行为。我从来不知道需要工厂工厂的实例。