工厂模式和抽象工厂模式是创建型设计模式中的两种,主要用于对象的创建,并且通过将对象的创建过程封装起来,来实现代码的解耦和灵活性。下面通过具体实例来说明这两种模式的用法及其在解耦中的作用。
工厂模式(Factory Method Pattern)
工厂模式通过定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
实例说明
假设我们有一个交通工具接口 Vehicle
以及具体实现类 Car
和 Bike
。我们通过工厂模式来创建这些交通工具对象。
接口和实现类
// Vehicle.java
public interface Vehicle {
void drive();
}
// Car.java
public class Car implements Vehicle {
@Override
public void drive() {
System.out.println("Driving a car.");
}
}
// Bike.java
public class Bike implements Vehicle {
@Override
public void drive() {
System.out.println("Riding a bike.");
}
工厂类
// VehicleFactory.java
public abstract class VehicleFactory {
public abstract Vehicle createVehicle();
}
// CarFactory.java
public class CarFactory extends VehicleFactory {
@Override
public Vehicle createVehicle() {
return new Car();
}
}
// BikeFactory.java
public class BikeFactory extends VehicleFactory {
@Override
public Vehicle createVehicle() {
return new Bike();
}
使用工厂模式
public class Main {
public static void main(String[] args) {
VehicleFactory carFactory = new CarFactory();
Vehicle car = carFactory.createVehicle();
car.drive(); // 输出: Driving a car.
VehicleFactory bikeFactory = new BikeFactory();
Vehicle bike = bikeFactory.createVehicle();
bike.drive(); // 输出: Riding a bike.
}
}
解耦作用
通过工厂模式,Main
类不需要知道具体的交通工具类,只需要知道工厂类和接口 Vehicle
。这使得代码更加灵活,增加了新类型的交通工具时不需要修改现有代码。
抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
实例说明
假设我们有一个家具工厂,可以创建椅子和沙发。我们通过抽象工厂模式来实现。
接口和实现类
// Chair.java
public interface Chair {
void sitOn();
}
// Sofa.java
public interface Sofa {
void lieOn();
}
// VictorianChair.java
public class VictorianChair implements Chair {
@Override
public void sitOn() {
System.out.println("Sitting on a Victorian chair.");
}
}
// ModernChair.java
public class ModernChair implements Chair {
@Override
public void sitOn() {
System.out.println("Sitting on a modern chair.");
}
}
// VictorianSofa.java
public class VictorianSofa implements Sofa {
@Override
public void lieOn() {
System.out.println("Lying on a Victorian sofa.");
}
}
// ModernSofa.java
public class ModernSofa implements Sofa {
@Override
public void lieOn() {
System.out.println("Lying on a modern sofa.");
}
抽象工厂类和具体工厂类
// FurnitureFactory.java
public interface FurnitureFactory {
Chair createChair();
Sofa createSofa();
}
// VictorianFurnitureFactory.java
public class VictorianFurnitureFactory implements FurnitureFactory {
@Override
public Chair createChair() {
return new VictorianChair();
}
@Override
public Sofa createSofa() {
return new VictorianSofa();
}
}
// ModernFurnitureFactory.java
public class ModernFurnitureFactory implements FurnitureFactory {
@Override
public Chair createChair() {
return new ModernChair();
}
@Override
public Sofa createSofa() {
return new ModernSofa();
}
}
使用抽象工厂模式
public class Main {
public static void main(String[] args) {
FurnitureFactory victorianFactory = new VictorianFurnitureFactory();
Chair victorianChair = victorianFactory.createChair();
Sofa victorianSofa = victorianFactory.createSofa();
victorianChair.sitOn(); // 输出: Sitting on a Victorian chair.
victorianSofa.lieOn(); // 输出: Lying on a Victorian sofa.
FurnitureFactory modernFactory = new ModernFurnitureFactory();
Chair modernChair = modernFactory.createChair();
Sofa modernSofa = modernFactory.createSofa();
modernChair.sitOn(); // 输出: Sitting on a modern chair.
modernSofa.lieOn(); // 输出: Lying on a modern sofa.
}
}
解耦作用
抽象工厂模式通过将具体工厂类与产品对象的创建过程分离,使得客户端代码仅依赖于工厂接口和产品接口。这样,增加新的家具风格时,只需添加新的具体工厂类和产品类,不需要修改现有代码。这种方式大大提高了系统的扩展性和可维护性。
总结
- 工厂模式通过定义一个创建对象的接口,使得具体类的实例化过程延迟到子类,从而实现了创建对象的灵活性和代码的解耦。
- 抽象工厂模式则进一步扩展,通过提供一个创建一系列相关或相互依赖对象的接口,使得产品族的创建过程独立于客户端代码,极大地提高了系统的可扩展性和可维护性。
两种模式都通过将对象的创建过程封装起来,实现了代码的解耦,使得系统更加灵活、易于扩展和维护。