java设计模式之工厂系列
2012-08-27 08:34
447 查看
工厂模式
在讲工厂模式之前先了解下单例模式
单例模式的要点
显然单例模式的要点有三个;一是某各类只能有一个实例;二是它必须自行创建这个事例;三是它必须自行向整个系统提供这个实例。在下面的对象图中,有一个"单例对象",而"客户甲"、"客户乙" 和"客户丙"是单例对象的三个客户对象。可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。
下面给出把Car设计成单例模式的代码:
这样就只有Car自己才能创建一个Car类,如果为一个司机提供一个Car代码如下:
以上是单例,如果在Car类中加入如下语句:
这样在调用getInstance时可以返回cars里面的任意一个Car,这种叫做多例,一个实例就是JDBC中的连接池。下面来看看简单工厂,如果我们想要控制它的生产过程首先我们要抽象出来一个接口Moveable代码如下:
让Car,Plane,Broom去实现这个接口代码如下:
然后抽象出来一个VehicleFactory用来控制生产过程代码如下:
这样PlaneFactory,CarFactory,BroomFactory就可以来继承了,从而实现多态,代码如下:
测试的代码就是下面这样的:
这样要生产出不同的东西只需要new出不同的工厂就可以了。如下图所示:
下面介绍抽象工厂,是如果想换掉一系列产品,就是用抽象工厂。
首先抽象出Vehicle,代码如下:
然后Car从Vehicle继承代码如下:
然后Broom从Vehicle继承代码如下:
然后抽象出Food代码如下:
Apple从Food继承代码如下:
MushRoom从Food继承代码如下:
然后抽象出Weapon代码如下:
AK47从Weapon继承代码如下:
MagicStick从Weapon继承代码如下:
然后抽象出来一个AbstractFactory代码如下:
在它里面有一些抽象方法用来产生Vehicle,Weapon,Food,而对于具体产生什么要看继承他的具体类的实现MagicFactory 代码如下:
DefaultFactory代码如下:
测试类的代码如下:
这样当我想要整体更换时只需要new 出新的Factory就行了,这就是抽象工厂。它的一个实例如界面换皮肤,皮肤换了按钮,菜单都跟着换了。
总结简单工厂的缺点是容易造成工厂泛滥,而抽象工厂的缺点是在产生产品系列的时候要改动的地方太多。
下面介绍在配置文件中来指定所要new的对象,sping.properties配置文件如下:
Test代码如下:
上面首先从配置文件中读出vehicleTypeName然后利用反射来取得这个对象。
下面用spring来代替上面的,首先建立一个配置文件applicationContext.xml
然后在Test中只需要这样写就可以了:
当然要注意加入spring的相应的jar包。
在讲工厂模式之前先了解下单例模式
单例模式的要点
显然单例模式的要点有三个;一是某各类只能有一个实例;二是它必须自行创建这个事例;三是它必须自行向整个系统提供这个实例。在下面的对象图中,有一个"单例对象",而"客户甲"、"客户乙" 和"客户丙"是单例对象的三个客户对象。可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。
下面给出把Car设计成单例模式的代码:
public class Car { public Car(){} private static Car car = new Car(); public static Car getInstance() { return car; } public void run() { System.out.println("冒着烟奔跑中car......."); } }
这样就只有Car自己才能创建一个Car类,如果为一个司机提供一个Car代码如下:
public class Test { public static void main(String[] args) { Car c1 = Car.getInstance(); Car c2 = Car.getInstance(); If(c1==c2) System.out.println("same car"); } }
以上是单例,如果在Car类中加入如下语句:
private static List<Car> cars = new ArrayList<Car>();
这样在调用getInstance时可以返回cars里面的任意一个Car,这种叫做多例,一个实例就是JDBC中的连接池。下面来看看简单工厂,如果我们想要控制它的生产过程首先我们要抽象出来一个接口Moveable代码如下:
public interface Moveable { void run(); }
让Car,Plane,Broom去实现这个接口代码如下:
public class Broom implements Moveable { public void run() { System.out.println("一路沙尘暴飞奔而来broom....."); } } public class Plane implements Moveable { public void run() { System.out.println("扇着翅膀前进中plane...."); } } public class Car implements Moveable { public void run() { System.out.println("冒着烟奔跑中car......."); } }
然后抽象出来一个VehicleFactory用来控制生产过程代码如下:
public abstract class VehicleFactory { abstract Moveable create(); }
这样PlaneFactory,CarFactory,BroomFactory就可以来继承了,从而实现多态,代码如下:
public class BroomFactory extends VehicleFactory{ public Moveable create() { return new Broom(); } } public class CarFactory extends VehicleFactory{ public Moveable create() { return new Car(); } } public class PlaneFactory extends VehicleFactory{ public Moveable create() { return new Plane(); } }
测试的代码就是下面这样的:
public class Test { public static void main(String[] args) { //Car c = Car.getInstance(); //Car c2 = Car.getInstance(); VehicleFactory factory = new BroomFactory(); Moveable m = factory.create(); //if(c == c2) System.out.println("same car"); m.run(); } }
这样要生产出不同的东西只需要new出不同的工厂就可以了。如下图所示:
下面介绍抽象工厂,是如果想换掉一系列产品,就是用抽象工厂。
首先抽象出Vehicle,代码如下:
public abstract class Vehicle { public abstract void run(); }
然后Car从Vehicle继承代码如下:
public class Car extends Vehicle { public void run() { System.out.println("冒着烟奔跑中car......."); } }
然后Broom从Vehicle继承代码如下:
public class Broom extends Vehicle{ public void run() { System.out.println("一路沙尘暴飞奔而来broom....."); } }
然后抽象出Food代码如下:
public abstract class Food { public abstract void printName(); }
Apple从Food继承代码如下:
public class Apple extends Food { public void printName() { System.out.println("apple"); } }
MushRoom从Food继承代码如下:
public class MushRoom extends Food { @Override public void printName() { // TODO Auto-generated method stub System.out.println("mushroom"); } }
然后抽象出Weapon代码如下:
public abstract class Weapon { public abstract void shoot(); }
AK47从Weapon继承代码如下:
public class AK47 extends Weapon{ public void shoot() { System.out.println("哒哒哒..."); } }
MagicStick从Weapon继承代码如下:
public class MagicStick extends Weapon { @Override public void shoot() { System.out.println("fire hu hu hu ..."); } }
然后抽象出来一个AbstractFactory代码如下:
public abstract class AbstractFactory { public abstract Vehicle createVehicle(); public abstract Weapon createWeapon(); public abstract Food createFood(); }
在它里面有一些抽象方法用来产生Vehicle,Weapon,Food,而对于具体产生什么要看继承他的具体类的实现MagicFactory 代码如下:
public class MagicFactory extends AbstractFactory { @Override public Food createFood() { // TODO Auto-generated method stub return new MushRoom(); } @Override public Vehicle createVehicle() { // TODO Auto-generated method stub return new Broom(); } @Override public Weapon createWeapon() { // TODO Auto-generated method stub return new MagicStick(); } }
DefaultFactory代码如下:
public class DefaultFactory extends AbstractFactory{ @Override public Food createFood() { // TODO Auto-generated method stub return new Apple(); } @Override public Vehicle createVehicle() { // TODO Auto-generated method stub return new Car(); } @Override public Weapon createWeapon() { // TODO Auto-generated method stub return new AK47(); } }
测试类的代码如下:
public class Test { public static void main(String[] args) { //DefaultFactory f = new DefaultFactory(); AbstractFactory f = new DefaultFactory(); Vehicle v = f.createVehicle(); v.run(); Weapon w = f.createWeapon(); w.shoot(); Food a = f.createFood(); a.printName(); } }
这样当我想要整体更换时只需要new 出新的Factory就行了,这就是抽象工厂。它的一个实例如界面换皮肤,皮肤换了按钮,菜单都跟着换了。
总结简单工厂的缺点是容易造成工厂泛滥,而抽象工厂的缺点是在产生产品系列的时候要改动的地方太多。
下面介绍在配置文件中来指定所要new的对象,sping.properties配置文件如下:
VehicleType=com.bjsxt.spring.factory.Car
Test代码如下:
public class Test { /** * @param args * @throws IOException */ public static void main(String[] args) throws Exception { Properties props = new Properties(); props.load(Test.class.getClassLoader().getResourceAsStream("com/bjsxt/spring/factory/spring.properties")); String vehicleTypeName = props.getProperty("VehicleType"); Object o = Class.forName(vehicleTypeName).newInstance(); Moveable m = (Moveable)o; m.run(); } }
上面首先从配置文件中读出vehicleTypeName然后利用反射来取得这个对象。
下面用spring来代替上面的,首先建立一个配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="v" class="com.bjsxt.spring.factory.Train"> </bean> <!-- //v=com.bjsxt.spring.factory.Car --> </beans>
然后在Test中只需要这样写就可以了:
public class Test { /** * @param args * @throws IOException */ public static void main(String[] args) throws Exception { BeanFactory f = new ClassPathXmlApplicationContext("com/bjsxt/spring/factory/applicationContext.xml"); Object o = f.getBean("v"); Moveable m = (Moveable)o; m.run(); } }
当然要注意加入spring的相应的jar包。
相关文章推荐
- [Java] 设计模式之工厂系列 02-面向抽象编程 抽象工厂 - 缺点 : 产生新的产品品种的时候,改动太多
- java设计模式之工厂系列_Factory_Series_DesignPattern
- JAVA设计模式之工厂系列
- Java设计模式之工厂系列(Factory)
- java设计模式系列--简单工厂模式
- [Java] 设计模式之工厂系列 01 简单工厂 - 缺点 :产生产品系列的时候很麻烦,会工厂泛滥
- [Java] 设计模式之工厂系列 03- spring.properties 的键值读取 / Spring3.0 读取 比较
- JAVA系列-设计模式-工厂模式
- [Java] 设计模式之工厂系列 01 简单工厂 - 缺点 :产生产品系列的时候很麻烦,会工厂泛滥
- [Java] 设计模式之工厂系列 03- spring.properties 的键值读取 / Spring3.0 读取 比较
- [Java] 设计模式之工厂系列 04 (自定义模拟 spring 读取xml文件 beanFactory)
- 常用Java设计模式系列(5)- 简单工厂、工厂方法模式和抽象工厂模式
- [Java] 设计模式之工厂系列 04 (自定义模拟 spring 读取xml文件 beanFactory)
- [Java] 设计模式之工厂系列 02-面向抽象编程 抽象工厂 - 缺点 : 产生新的产品品种的时候,改动太多
- Java设计模式-工厂模式
- Java之------单机版书店管理系统(设计思想和设计模式系列二)用户模块
- java设计模式_简单工厂模式
- java 设计模式学习笔记二 工厂模式Factory
- java设计模式一 简单工厂模式
- JAVA设计模式之工厂模式