Java与设计模式(01)--简单工厂模式

简单工厂模式的思想很简单:根据传入的参数,工厂的produce()方法创建不同类的对象。


首先,由于创建出来的对象分数不同的Class,所以这些Class都应该inherit一个parent class,考虑到我们对接口编程的思想,我们定义一个继承关系:

Car

public interface Car {
  public void go();
}

Bus

public class Bus implements Car {
  @Override
  public void go() {
    System.out.println("Bus is going...");
  }
}

Truck

public class Truck implements Car {
  @Override
  public void go() {
    System.out.println("Truck is going...");
  }
}

接下来需要定义工厂和参数类:

CarType

public enum CarType {
	Bus, Truck
}

CarFactory,考虑到调用者使用的方便,我们使用静态方法创建Car的实例。实际使用中更有可能的是参数并不是CarType,而是实际的属性值,通过属性值的不同格式或内容创建不同类型的实例(例如,可以使用"Mr. White"的形式创建一个名为"White"的男人,也可以通过"Miss Mary"的形式创建一个"Mary"小姐,这样,传入参数都是String,但创建的对象分别是男人和女人:

public class CarFactory {
  public static Car produce(CarType type) {
    switch (type) {
    case Bus:
      return new Bus();
    case Truck:
      return new Truck();
    default:
      return null;
    }
  }
}

最后通过例子来测试一下:

public class Test {
	public static void main(String[] args) {
		Car car = CarFactory.produce(CarType.Bus);
		car.go();
	}
}



通过上面的例子我们能够知道:

  1. 如果需要扩展Car的继承类,只需要编写新的类,并且在CarFactory的produce()方法中增加逻辑即可;
  2. 因为增加Car的具体实现类需要修改produce方法,所以灵活性不是很强;
  3. 关键业务代码都在Factory中,没能很好的实现“松耦合”;

针对以上现实,实际开发中我们存在另外一种情况,我们通过传入的参数(类名)确定生产出的对象:

改进后的Factory类:

public class CarFactory {
	public static Car produce(CarType type) {
		switch (type) {
		case Bus:
			return new Bus();
		case Truck:
			return new Truck();
		default:
			return null;
		}
	}
	
	public static Car produce(String type) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		Class<?> carClass = Class.forName(type);
		return (Car) carClass.newInstance();
	}
}

测试类代码:

public class Test {
	public static void main(String[] args) {
//		Car car = CarFactory.produce(CarType.Bus);
//		car.go();
		Car car;
		try {
			car = CarFactory.produce("com.freesoft.designpattern.simplefactory.Bus");
			car.go();
			car = CarFactory.produce("com.freesoft.designpattern.simplefactory.Truck");
			car.go();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}

这样如果今后需要创建一个新的汽车类型(Sedan),我们仅需要编写Sedan这个Class即可,在测试类中就可以通过传入类名创建Sedan对象,而无需修改Factory代码。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值