1. 工厂方法简介
定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类
- Product(产品):所有产品的顶级父类,可以是抽象类或者接口。对应下面代码中的Human
- ConcreteProduct(子产品):由产品类Product派生出的产品子类,可以有多个产品子类。对应下面代码中的不同人种
- Factory(工厂接口):定义工厂方法的工厂接口,当然也可以是抽象类,它使顶级工厂制造方法抽象化、标准统一化
- ConcreteFactory(工厂实现):实现了工厂接口的工厂实现类,并决定工厂方法中具体返回哪种产品子类的实例
2. 代码示例
package designpattern;
/*
*
* 人类抽象类
*/
abstract class Human {
public abstract void color();
public abstract void talk();
}
/*
* 黑种人类
*/
class BlackMan extends Human {
@Override
public void color() {
System.out.println("我的皮肤是黑色");
}
@Override
public void talk() {
System.out.println("我是黑种人");
}
}
/*
* 黄种人类
*/
class YellowMan extends Human {
@Override
public void color() {
System.out.println("我的皮肤是黄色");
}
@Override
public void talk() {
System.out.println("我是黄种人");
}
}
/*
* 白种人类
*/
class WhiteMan extends Human {
@Override
public void color() {
System.out.println("我的皮肤是白色");
}
@Override
public void talk() {
System.out.println("我是白种人");
}
}
/*
* 工厂接口
*/
interface HumanFactory {
public Human create();
}
/*
* 具体的工厂
*/
class BlackManFactory implements HumanFactory {
@Override
public Human create() {
return new BlackMan();
}
}
class YellowManFactory implements HumanFactory {
@Override
public Human create() {
return new YellowMan();
}
}
class WhiteManFactory implements HumanFactory {
@Override
public Human create() {
return new WhiteMan();
}
}
public class FactoryDemo {
public static void main(String[] args) {
Human human = null;
HumanFactory factory = null;
// 产生一个黑种人
factory = new BlackManFactory();
human = factory.create();
human.talk();
human.color();
// 产生一个黄种人
factory = new WhiteManFactory();
human = factory.create();
human.talk();
human.color();
// 产生一个白种人
factory = new WhiteManFactory();
human = factory.create();
human.talk();
human.color();
}
}
3. 工厂方法的优点
- 良好的封装性,代码结构清晰
- 拓展性好,增加一个产品时,只需要增加一个产品类和一个产品工厂即可(如果再加一个肤色的人种,再创建一个肤色人类和工厂即可)
- 屏蔽产品类,调用者不用关心产品类的的变化,只需要关心产品的抽象类中的抽象方法(以jdbc为例,存在MySql和Oracle产品,,MySql和Oracle工厂,保证产品的抽象方法不变的情况下,更换驱动名称即可切换不同的驱动,这里更换名称就是产品类和工厂)
4. 简单工厂
场景中只需要1个工厂类的话,就不需要先定义工厂接口再实现具体的工厂类了
package designpattern;
/*
*
* 人类抽象类
*/
abstract class Human {
public abstract void color();
public abstract void talk();
}
/*
* 黑种人类
*/
class BlackMan extends Human {
@Override
public void color() {
System.out.println("我的皮肤是黑色");
}
@Override
public void talk() {
System.out.println("我是黑种人");
}
}
/*
* 黄种人类
*/
class YellowMan extends Human {
@Override
public void color() {
System.out.println("我的皮肤是黄色");
}
@Override
public void talk() {
System.out.println("我是黄种人");
}
}
/*
* 白种人类
*/
class WhiteMan extends Human {
@Override
public void color() {
System.out.println("我的皮肤是白色");
}
@Override
public void talk() {
System.out.println("我是白种人");
}
}
/*
* 工厂接口
*/
class HumanFactory {
public Human create(String color) {
switch (color) {
case "white":
return new WhiteMan();
case "black":
return new BlackMan();
case "yellow":
return new YellowMan();
}
return null;
}
}
public class FactoryDemo {
public static void main(String[] args) {
Human human = null;
HumanFactory factory = new HumanFactory();
// 产生一个黑种人
human = factory.create("black");
human.talk();
human.color();
// 产生一个黄种人
human = factory.create("yellow");
human.talk();
human.color();
// 产生一个白种人
human = factory.create("white");
human.talk();
human.color();
}
}
对比工厂方法的代码,可以看出简单工厂有以下改变:
- 没有了工厂接口,只有1个具体的工厂类
- 创建不同的产品时没有根据不同的工厂进行生产,而是根据不同的参数进行生产