简单工厂模式
简单的工厂模式,就是把实例的创建单独提取在一个类里去完成。
比如:有一个接口 Car,和三个具体品牌:BMW,BENZ,BYD。创建一个 CarFactory 工厂类来生产car,当我需要 Car 的实例时,通过工厂来创建。
//car接口
public interface Car {
public void run();
}
//三个具体的实现类
public class BMW implements Car{
@Override
public void run() {
System.out.println("一辆宝马车在跑");
}
}
public class BENZ implements Car{
@Override
public void run() {
System.out.println("一辆奔驰车在跑");
}
}
public class BYD implements Car{
@Override
public void run() {
System.out.println("一辆比亚迪在跑");
}
}
//SimpleFactory工厂类,用来实例化 Car,生产车
public class SimpleFactory {
public static Car getCar(String carName){
if(carName.equals("BENZ")){
return new BENZ();
}else if(carName.equals("BMW")){
return new BMW();
}else if(carName.equals("BYD")){
return new BYD();
}else{
return null;
}
}
}
//测试类
public class Test {
public static void main(String[] args) {
Car car1 = SimpleFactory.getCar("BMW");
car1.run();
Car car2 = SimpleFactory.getCar("BENZ");
car2.run();
Car car3 = SimpleFactory.getCar("BYD");
car3.run();
}
}
简单工厂还有两种写法:一种是利用了反射,一种是在工厂里写多个方法。
不同的写法各有利弊:
利用反射,好处是当增加产品的时候不用修改工厂类的代码,缺点就是写法复杂,不易用
public class StaticFactory {
@SuppressWarnings("unchecked")
public static <T extends Car> T newInstance(Class<T> claz){
T result = null;
try {
result = (T) Class.forName(claz.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
多方法是在工厂类的写多个方法,当需要扩展的时候,只需要增加一个方法即可,不用修改原代码的逻辑;而只有一个方法的写法,要在方法内部用 if 或是 switch 进行判断,要扩展就要增加判断语句。
public class MultiFactory {
public static Car getBenz(){
return new BENZ();
}
public static Car getBmw(){
return new BMW();
}
public static Car getByd(){
return new BYD();
}
}
工厂方法模式
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化哪一个。
工厂方法模式等于把工厂也抽象了一层。
当需求变化,只需要增删相应的类,不需要修改已有的类。
//抽象的工厂类
public abstract class AbstractFactory {
public abstract Car getCar();
}
//具体的工厂类
public class BenzFactory extends AbstractFactory{
@Override
public Car getCar() {
return new BENZ();
}
}
public class BmwFactory extends AbstractFactory{
@Override
public Car getCar() {
return new BMW();
}
}
//当需要增加 BYD 工厂时,直接增加一个实现类即可,不用再修改原来的工厂
public class BydFactory extends AbstractFactory{
@Override
public Car getCar() {
return new BYD();
}
}
//测试类
public class Test {
public static void main(String[] args) {
AbstractFactory factory = new BenzFactory();
Car car = factory.getCar();
car.run();
}
}
抽象工厂模式
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
抽象工厂模式面对是产品族,就是可视为一组的多个产品,抽象工厂 模式能保证客户端始终只使用同一个产品族中的对象。比如:汽车和自行车是不同的产品,有一个抽象工厂生产汽车和自行车,BYD是一个具体的工厂,生产货车和产公路自行车;BMW也是一个具体的工厂,生产客车和山地自行车。
工厂方法模式面对的是单一产品,而抽象工厂模式面对的是产品族,这是二者最大的区别。
//产品接口和具体实现类
//汽车接口和实现类
public interface Car {
public void run();
}
public class Bus implements Car{
@Override
public void run() {
System.out.println("一辆公交车在跑");
}
}
public class Truck implements Car{
@Override
public void run() {
System.out.println("一辆货车在跑");
}
}
//自行车接口和实现类
public interface Bike {
public void run();
}
public class MountainBike implements Bike{
@Override
public void run() {
System.out.println("一辆山地自行车在跑");
}
}
public class RoadBike implements Bike{
@Override
public void run() {
System.out.println("一辆公路自行车在跑");
}
}
//抽象的工厂类
public abstract class AbstractFactory {
//生产抽象的产品
public abstract Car getCar();
public abstract Bike getBike();
}
//具体的工厂类
public class BmwFactory extends AbstractFactory{
@Override //Bmw工厂生产客车和山地自行车
public Car getCar() {
System.out.println("这是 BMW 工厂生产的客车 ");
return new Bus();
}
@Override
public Bike getBike() {
System.out.println("这是 BMW 工厂生产的山地自行车 ");
return new MountainBike();
}
}
public class BydFactory extends AbstractFactory{
@Override //Byd工厂生产货车和公路自行车
public Car getCar() {
System.out.println("这是 BYD 工厂生产的货车 ");
return new Truck();
}
@Override
public Bike getBike() {
System.out.println("这是 BYD 工厂生产的公路自行车 ");
return new RoadBike();
}
}
//测试类
public class Test {
public static void main(String[] args) {
AbstractFactory factoryByd = new BydFactory();
factoryByd.getBike().run();
factoryByd.getCar().run();
AbstractFactory factoryBmw = new BmwFactory();
factoryBmw.getBike().run();
factoryBmw.getCar().run();
}
}
工厂模式就是把实例对象的产生封装起来,只要知道工厂类,就能创建出实例来,而不用关心实例是如何创建出来的,使创建和使用分离,达到解耦的目的。
工厂模式适用于构建同产品类型(同一个接口或基类)的不同对象时,尤其是当创建实例的条件比较复杂时,或是创建对象需要很多参数而这些参数中大部分又是固定的时候,工厂模式的优点就很明显了。当然,缺点也很明显,不容易扩展,要增加一个产品就要修改多处代码。