工厂模式目的是封装对象的创建过程,将对象的创建和使用分离开来,从而提高代码的可维护性和可扩展性。下面是它们之间的区别:
简单工厂模式可以很好地隐藏对象创建的细节,使得客户端代码不必关心具体对象的创建过程。但是简单工厂模式也有缺点,例如当需要添加新的产品类时,就必须修改工厂类的代码,这违反了开闭原则。
public class AnimalFactory {
public static Animal createAnimal(String type) {
if (type.equals("Dog")) {
return new Dog();
} else if (type.equals("Cat")) {
return new Cat();
} else {
throw new IllegalArgumentException("Invalid animal type: " + type);
}
}
}
public interface Animal {
void speak();
}
public class Dog implements Animal {
@Override
public void speak() {
System.out.println("Woof!");
}
}
public class Cat implements Animal {
@Override
public void speak() {
System.out.println("Meow!");
}
}
public class Client {
public static void main(String[] args) {
Animal dog = AnimalFactory.createAnimal("Dog");
Animal cat = AnimalFactory.createAnimal("Cat");
Animal pig = AnimalFactory.createAnimal("pig");
dog.speak(); // Output: Woof!
cat.speak(); // Output: Meow!
pig.speak(); // Output: Invalid animal type: pig
}
}
工厂方法模式通常通过一个抽象工厂接口和多个具体工厂实现类来实现。
// 抽象产品接口
interface Car {
void run();
}
// 具体产品实现类1
class Benz implements Car {
@Override
public void run() {
System.out.println("Benz is running.");
}
}
// 具体产品实现类2
class BMW implements Car {
@Override
public void run() {
System.out.println("BMW is running.");
}
}
// 抽象工厂接口
interface CarFactory {
Car createCar();
}
// 具体工厂实现类1
class BenzFactory implements CarFactory {
@Override
public Car createCar() {
return new Benz();
}
}
// 具体工厂实现类2
class BMWFactory implements CarFactory {
@Override
public Car createCar() {
return new BMW();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
// 创建奔驰车
CarFactory benzFactory = new BenzFactory();
Car benzCar = benzFactory.createCar();
benzCar.run();
// 创建宝马车
CarFactory bmwFactory = new BMWFactory();
Car bmwCar = bmwFactory.createCar();
bmwCar.run();
}
}
抽象工厂模式的核心思想是“工厂的工厂”。这意味着,不同的工厂可以创建不同的对象家族,而不是单个对象。这些工厂可以是具体的类,也可以是抽象类或接口。客户端使用这些工厂接口创建对象,而无需知道底层的实现细节。
// 定义抽象工厂接口
interface AbstractFactory {
public ProductA createProductA();
public ProductB createProductB();
}
// 定义具体工厂类
class ConcreteFactory1 implements AbstractFactory {
public ProductA createProductA() {
return new ConcreteProductA1();
}
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
class ConcreteFactory2 implements AbstractFactory {
public ProductA createProductA() {
return new ConcreteProductA2();
}
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
// 定义产品接口
interface ProductA {
public String getDescription();
}
interface ProductB {
public String getDescription();
}
// 定义具体产品类
class ConcreteProductA1 implements ProductA {
public String getDescription() {
return "Product A1";
}
}
class ConcreteProductA2 implements ProductA {
public String getDescription() {
return "Product A2";
}
}
class ConcreteProductB1 implements ProductB {
public String getDescription() {
return "Product B1";
}
}
class ConcreteProductB2 implements ProductB {
public String getDescription() {
return "Product B2";
}
}
// 使用抽象工厂创建产品
public class Client {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
AbstractFactory factory2 = new ConcreteFactory2();
ProductA productA1 = factory1.createProductA();
ProductB productB1 = factory1.createProductB();
ProductA productA2 = factory2.createProductA();
ProductB productB2 = factory2.createProductB();
}
}
在这个例子中,AbstractFactory
接口定义了两个方法 createProductA
和 createProductB
,用于创建产品 A 和产品 B。具体工厂类 ConcreteFactory1
和 ConcreteFactory2
分别实现了这个接口,每个工厂都可以创建自己的一组产品。产品由 ProductA
和 ProductB
接口定义,而具体的产品类 ConcreteProductA1
,ConcreteProductA2
,ConcreteProductB1
和 ConcreteProductB2
实现了这些接口。
在Java中,使用new关键字创建对象是主动获取资源的方式,应用与资源之间是直接依赖的。而采用工厂模式获取对象时,是应用向工厂要对象,工厂从容器中获取对象返回给应用,是被动的,从而降低了应用和资源之间的依赖关系。这种主动权的变化就叫控制反转。
静态工厂方法可以通过方法名字来表示创建了什么对象,比如下面这个方法,就表示创建一个可能是素数的BigInteger,所以,你可以通过名字来表明对象的作用。
总之,静态工厂模式和new创建对象有很大的区别。静态工厂模式可以降低应用和资源之间的依赖关系,使得代码更加灵活、可维护性更高;而new创建对象则是主动获取资源的方式。
工厂方法模式:工厂方法模式通常只需要一个工厂接口和多个具体工厂类,客户端只需要调用工厂接口的方法即可创建对象。
抽象工厂模式:抽象工厂模式需要定义多个工厂接口和产品族接口,每个工厂接口和产品族接口都需要对应多个具体实现类,代码结构更加复杂。
简单工厂模式适用于创建单一类型的产品对象,工厂方法模式适用于创建多种类型的产品对象,而抽象工厂模式适用于创建多个产品族的对象。