Java23种设计模式之工厂模式

工厂工厂,顾名思义就是加工东西的。Java的工厂模式包含以下3种:

  • 简单工厂模式

  • 工厂方法模式

  • 抽象工厂模式

 1.简单工厂

使用场景:如果一个一些对象产品,已经确定不会再改动,就可以使用简单工厂模式

理解几个关键点

1)抽象产品角色:它一般是具体产品继承的父类或要实现的接口。

2)具体产品角色:工厂类创建的对象就是该角色的实例。

3)工厂类角色:含有一定的业务逻辑和判断逻辑。

代码实例:

/**
 * 抽象产品定义
 * */
public interface Car {

	/**
	 * 只要能跑就行
	 * */
	void run();
}
/**
 * 具体产品(奔驰)定义:实现抽象产品
 * */
public class BenzCar implements Car{

	@Override
	public void run() {
		System.out.println("我是高级轿车Benz,我会跑");
	}

}
/**
 * 具体产品(宝马)定义:实现抽象产品
 * */
public class BMWCar implements Car{

	@Override
	public void run() {
		System.out.println("我是高级轿车BMW,我会跑");
		
	}

}
/**
 * 定义一个生产车的工厂
 * */
public class CarFactory {

	public Car createCar(String carType) {
		Car car = null;
		switch (carType) {
		case "1":
			car = new BMWCar();//宝马车
			break;
		case "2":
			car = new BenzCar();//奔驰车
			break;
		}
		return car;
	}
}
public class Client {

	public static void main(String[] args) {
		//生成一个工厂类
		CarFactory carFactory = new CarFactory(); 
		/**
		 * 客户:我要一辆宝马车
		 * 工厂:好的,马上给你
		 **/
		Car bmwCar = carFactory.createCar("1");
		bmwCar.run();
		
		/**
		 * 客户:我还想在要一辆奔驰车
		 * 工厂:好的,马上给你
		 **/
		Car benzCar = carFactory.createCar("2");
		benzCar.run();
	}
}

输出结果:
我是高级轿车BMW,我会跑
我是高级轿车Benz,我会跑

在将工厂方法和抽象工厂模式前,先介绍两个概念,若你把这两个概念搞懂了,理解工厂方法和抽象工厂模式就容易多了。

1)产品等级结构:产品等级结构即产品的继承结构。如一个抽象类是车,其子类有奔驰车,宝马车,大众车等,则抽象车与具体品牌的车之间构成了一个产品等级结构,抽象车是父类,而具体品牌的车是其子类。

2)产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。如宝马车工厂生产的宝马轿车,宝马SUV,宝马卡车,宝马轿车位于轿车产品等级结构中,宝马卡车位于卡车产品等级结构中。宝马轿车和宝马卡车就构成一个产品族。

2.工厂方法

描述:工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。在同一等级结构中,支持增加任意产品。

理解几个关键点

1)抽象产品角色:它一般是具体产品继承的父类或要实现的接口。

2)具体产品角色:工厂类创建的对象就是该角色的实例。

3)抽象工厂角色:它一般是具体工厂角色继承的父类或要实现的接口。

3)具体工厂角色:含有一定的业务逻辑和判断逻辑。

代码实例:

/**
 * 抽象产品定义
 * */
public interface Car {

	/**
	 * 只要能跑就行
	 * */
	void run();
}
/**
 * 具体产品(奔驰)定义:实现抽象产品
 * */
public class BenzCar implements Car{

	@Override
	public void run() {
		System.out.println("我是高级轿车Benz,我会跑");
	}

}
/**
 * 具体产品(宝马)定义:实现抽象产品
 * */
public class BMWCar implements Car{

	@Override
	public void run() {
		System.out.println("我是高级轿车BMW,我会跑");
		
	}

}
/**
 * 定义一个抽象工厂角色(接口)
 * */
public interface IFactory {

	/**
	 * 生产各种品牌车
	 * */
	Car createCar();
}

/**
 * 定义具体的工厂(生产宝马)
 * */
public class BMWFactory implements IFactory{

	@Override
	public Car createCar() {
		return new BMWCar();
	}

}
/**
 * 定义具体的工厂(生产奔驰)
 * */
public class BenzFactory implements IFactory{

	@Override
	public Car createCar() {
		return new BenzCar();
	}

}
public class Client {

	public static void main(String[] args) {
		
		/**
		 * 客户:我要一辆宝马车
		 * 宝马工厂:好的,马上给你
		 **/
		IFactory bmwFactory = new BMWFactory();
		Car bmwCar = bmwFactory.createCar();
		bmwCar.run();
		
		/**
		 * 客户:我要一辆宝马车
		 * 奔驰工厂:好的,马上给你
		 **/
		IFactory benzFactory = new BenzFactory();
		Car benzCar = benzFactory.createCar();
		benzCar.run();
	}
}

 

3.抽象工厂

描述:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。

理解几个关键点

1)抽象产品角色:它一般是具体产品继承的父类或要实现的接口。

2)具体产品角色:工厂类创建的对象就是该角色的实例。

3)抽象工厂角色:它一般是具体工厂角色继承的父类或要实现的接口。

3)具体工厂角色:含有一定的业务逻辑和判断逻辑。

代码实例:

/**
 * 定义抽象产品:轿车
 * */
public interface Sedan {

	void sedanName();
}

/**
 * 定义抽象产品:卡车
 * */
public interface Truck {

	void truckName();
}
/**
 * 定义具体产品:宝马轿车
 * */
public class BMWSedan implements Sedan{

	@Override
	public void sedanName() {
		System.out.println("我是宝马轿车");
		
	}
}



/**
 * 定义具体产品:奔驰轿车
 * */
public class BenzSedan implements Sedan{

	@Override
	public void sedanName() {
		System.out.println("我是奔驰轿车");
		
	}

}
/**
 * 定义具体产品:宝马卡车
 * */
public class BMWTruck implements Truck{

	@Override
	public void truckName() {
		System.out.println("我是宝马卡车");
		
	}

}



/**
 * 定义具体产品:奔驰卡车
 * */
public class BenzTruck implements Truck{

	@Override
	public void truckName() {
		System.out.println("我是奔驰卡车");
		
	}

}
/**
 * 定义抽象工厂
 * */
public interface IFactory {

	/**
	 * 生产轿车
	 * */
	Sedan createSedan();
	
	/**
	 * 生产卡车
	 * */
	Truck createTruck();
}


/**
 * 定义具体工厂:宝马车生产工厂
 * */
public class BMWFactory implements IFactory{

	@Override
	public Sedan createSedan() {
		return new BMWSedan();
	}

	@Override
	public Truck createTruck() {
		return new BMWTruck();
	}

}


/**
 * 定义具体工厂:奔驰车生产工厂
 * */
public class BenzFactory implements IFactory{

	@Override
	public Sedan createSedan() {
		return new BenzSedan();
	}

	@Override
	public Truck createTruck() {
		return new BenzTruck();
	}

}
public class Client {

	public static void main(String[] args) {
		/**
		 * 客户:我要一辆宝马轿车、一辆宝马卡车
		 * 宝马工厂:好的,马上给你
		 **/
		IFactory bmwFactory = new BMWFactory();
		Sedan bmwSedan = bmwFactory.createSedan();
		bmwSedan.sedanName();
		Truck bmwTruck = bmwFactory.createTruck();
		bmwTruck.truckName();
	}
}


输出结果:
我是宝马轿车
我是宝马卡车

4.总结

简单工厂模式:所有的业务逻辑判断都在工厂类中,后期每增加一个新产品,都需要修改工厂类,这种设计模式不符合开闭原则(对扩展开发,对修改封闭),不利于扩展。

工厂方法模式:是对简单工厂模式的进一步解耦,因为在工厂模式中是一个子类产品对应一个工厂类,而这些工厂类都是实现了抽象工厂类。这就相当于把原本会因为业务庞大的简单工厂类,拆分成一个个的工厂类(把业务逻辑部分放到了客户端去做),这样代码都不会耦合在同一个类中了,符合了开闭原则。但工厂方法模式的缺点是每增加一个产品类,就需要增加一个对应的工厂类,增加了额外的开发量。

抽象工厂模式:是工厂方法模式的进一步延伸,由于它提供了功能更为强大的工厂类并且具备较好的可扩展性。

主要优点如下:

       (1) 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。

       (2) 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。

       (3) 增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。

主要缺点如下:

       增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。

猜你喜欢

转载自blog.csdn.net/wang_zqiang/article/details/86626454