您的位置:首页 > 编程语言 > Java开发

java设计模式之工厂系列

2012-08-27 08:34 447 查看
工厂模式
在讲工厂模式之前先了解下单例模式

单例模式的要点

  显然单例模式的要点有三个;一是某各类只能有一个实例;二是它必须自行创建这个事例;三是它必须自行向整个系统提供这个实例。在下面的对象图中,有一个"单例对象",而"客户甲"、"客户乙" 和"客户丙"是单例对象的三个客户对象。可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。



下面给出把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包。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: