看字面意思,工厂是什么,工厂是用来生产制造产品的地方。这里的工厂也不例外,工厂方法模式又叫简单工厂。
它解决的是任意定制一类产品的问题。
(1)
首先,看一个段下程序,包含两个类:
一个是car类
package com.feng.factory;
public class Car {
public void run()
{
System.out.println("开着车,车跑了。。。。。");
}
}
一个是测试类Test
package com.feng.factory;
public class Test {
public static void main(String[] args) {
Car c = new Car();
c.run();
}
}
很简单的小程序,生成一个车的对象,执行它的run方法。
(2)
现在,我想可以使用任意的交通工具,不难想到,可以定义一个借口或者抽象类,使用多态的知识,就可以完成,而且扩展性也很好
代码如下:
Moveable接口类
package com.feng.factory;
public interface Moveable {
void run();
}
Car类,实现Moveable接口
package com.feng.factory;
public class Car implements Moveable{
public void run()
{
System.out.println("开着车,车跑了。。。。。");
}
}
Plane类,实现Moveable接口
package com.feng.factory;
public class Plane implements Moveable {
@Override
public void run() {
System.out.println("坐着飞机看风景。。。。");
}
}
测试类Test
package com.feng.factory;
public class Test {
public static void main(String[] args) {
//Car c = new Car();
Moveable m = new Plane();
m.run();
}
}
在测试类中,我想使用什么交通工具,就把new 换成什么交通工具即可。
(3)
但是现在就有一个问题,现在每个交通工具类的构造方法都是公开的,每个人都可以new,例如一个不会开飞机的人new了一个飞机,这不和逻辑
有时候我们就要去控制类的生产过程,在生产中加一些控制信息。接下来就是我们的工厂方法模式了。
我们会想,我们可以把交通工具的构造提出来,用一个类来实现,比如Plane,就给他增加一个PlaneFactory,把plane的生产过程放到PlaneFactory中
代码如下:
定义一个PlaneFactory
package com.feng.factory;
public class PlaneFactory {
public Plane creatPlane()
{//可以添加控制信息
return new Plane();
}
}
测试类代码Test如下
package com.feng.factory;
public class Test {
public static void main(String[] args) {
//Car c = new Car();
PlaneFactory planeFactory = new PlaneFactory();
Moveable m = planeFactory.creatPlane();
m.run();
}
}
这里测试类中,用户终于不能直接new了,我们可以在PlaneFactory中对Plane类对象的构造加以控制了,可以看一下要求new Plane的对象有没有这个权限等等。
(4)
但是如果我现在又想把Plane换成car了,是不是Test类中需要改两个地方,改动有点大,那怎么办,我们可以给工厂也提供出一个接口来。
代码如下:
工厂类接口Factory
package com.feng.factory;
public interface Factory {
Moveable create();
}
PlaneFactory类,实现Factory
package com.feng.factory;
public class PlaneFactory implements Factory{
@Override
public Moveable create() {
//可以加控制信息
return new Plane();
}
}
CarFactory类,实现Factory
package com.feng.factory;
public class CarFactory implements Factory{
@Override
public Moveable create() {
// TODO Auto-generated method stub
return new Car();
}
}
Car,Plane类用上面一样,不再贴了
测试类:
package com.feng.factory;
public class Test {
public static void main(String[] args) {
//Car c = new Car();
Factory Factory = new PlaneFactory();
Moveable m = Factory.create();
m.run();
}
}
如果想改变交通工具的话,只需要改new的工厂类就可以,其他的代码不需要变动,如果要添加新的交通工具,只要实现Moveable接口,在给新的交通工具建立一个工厂类,实现Factory接口即可。
接下来再看一个人类工厂:
其中工厂类使用了反射机制,只需要一个工厂实现类即可,实现代码如下:
抽象人类Person:
package com.feng.factory.Person;
public abstract class Person {
public abstract void getColor();
public abstract void talk();
}
黄种人YellowPerson,继承Person
package com.feng.factory.Person;
public class YellowPerson extends Person {
@Override
public void getColor() {
// TODO Auto-generated method stub
System.out.println("我是黄种人");
}
@Override
public void talk() {
// TODO Auto-generated method stub
System.out.println("黄种人说话了");
}
}
黑种人BlackPerson,继承Person
package com.feng.factory.Person;
public class BlackPerson extends Person {
@Override
public void getColor() {
// TODO Auto-generated method stub
System.out.println("我是黑种人");
}
@Override
public void talk() {
// TODO Auto-generated method stub
System.out.println("黑种人说话了");
}
}
白种人WhitePerson,继承Person
package com.feng.factory.Person;
public class WhitePerson extends Person {
@Override
public void getColor() {
// TODO Auto-generated method stub
System.out.println("我是白种人");
}
@Override
public void talk() {
// TODO Auto-generated method stub
System.out.println("白种人说话了");
}
}
人类工厂接口PersonFactory,使用范型,简化操作
package com.feng.factory.Person;
public interface PersonFactory {
<T extends Person> T create(Class<T> c);
}
人类制造工厂AllPersonFactory, 使用反射机制,可以根据参数不同产生不同的人种
package com.feng.factory.Person;
public class AllPersonFactory implements PersonFactory {
@Override
public <T extends Person> T create(Class<T> c) {
// TODO Auto-generated method stub
Person person = null;
try {
person = (T)Class.forName(c.getName()).newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("创造人失败");
}
return (T)person;
}
}
测试类Test
package com.feng.factory.Person;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
PersonFactory factory = new AllPersonFactory();
Person p = factory.create(YellowPerson.class);
p.talk();
p.getColor();
}
}
工厂方法模式是new一个对象的替代品,具有良好的封装性,扩展性,屏蔽产品类的特性。不过同时增加了代码的复杂性。