Factory (工厂)模式
工厂模式的定义:
假如你有一个类A,要实例化这个类,最简单的方法就是A a=new A()。如果要做一 些初始化的工作,通常会把这些操作写在A的构造方法里例如:A a =new A(parmeter);
但是,也许有很多的初始化内容,如果把所有内容都放在构造函数里面,就很不合适。在这种情境下就可以使用工厂模式,协助完成一系列初始化工作。
工厂模式通常有3种形态:简单工厂模式、工厂方法模式、抽象工厂模式。
下面就以农产品管理系统的集中水果和蔬菜(苹果、橘子、葡萄、番茄、冬瓜、胡萝卜)为例简要介绍这三种形态的工厂
一、Simple Factory(简单工厂)模式
SimpleFactory模式的结构如图
SimpleFactory模式的目的是专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有相同的父类
代码实现
//定义水果(Fruit)接口
public interface Fruit {
public void grow(); //水果是被栽培的
public void expressedJuice();//水果是可以榨汁的
}
//定义苹果类实现水果接口
public class Apple implements Fruit {
@Override
public void grow() {
System.out.println("栽培苹果");
}
@Override
public void expressedJuice() {
System.out.println("榨苹果汁");
}
}
//定义葡萄类实现水果接口
public class Grape implements Fruit{
@Override
public void grow() {
System.out.println("栽培葡萄");
}
@Override
public void expressedJuice() {
System.out.println("榨葡萄汁");
}
}
//定义橙子类实现水果接口
public class Orange implements Fruit{
@Override
public void grow() {
System.out.println("栽培橘子");
}
@Override
public void expressedJuice() {
System.out.println("榨橙汁");
}
}
//定义水果工厂(FruitFactory)类
public class FruitFactory {
public Fruit trafficFruit(int which) {
if(which==1) {//如果是1,则返回苹果实例
return new Apple();
}else if(which==2){//如果是2,则返回葡萄实例
return new Grape();
}else if (which==3) {//如果是3,则返回橙子实例
return new Orange();
}else {
return null;
}
}
}
//编写客户(Client)类
public class Client {
public static void main(String[] args) {
FruitFactory fruit = new FruitFactory();//实例化水果工厂,可以开始运输水果了
fruit.trafficFruit(1).expressedJuice();//调用苹果的expressedJuice()方法,用于榨苹果汁
fruit.trafficFruit(2).expressedJuice();//调用葡萄的expressedJuice()方法,用于榨葡萄汁
fruit.trafficFruit(3).expressedJuice();//调用橙子的expressedJuice()方法,用于榨橙汁
}
}
输出结果:
从上面代码可以看出,当要运送水果时,只需向水果工厂(FruitFactory)请求就可以了。水果工厂在街道请求后,会自行判断创建和提供哪种水果。
二、Factory Method(工厂方法)模式
对于简单工厂模式,如果要引增加一种或者几种水果就比较麻烦。这是除了要定义及个新增的水果类外,还必须修改水果工厂和客户端。从而可以看出比较麻烦,Simple Factory 模式开放性比较差。
要解决这种开放性比较差的问题,需要用到下面介绍的Factory Method(工厂方法模式)
Factory Method模式的结构如图
代码实现
//将水果工厂定义为接口而不是类
public interface FruitFactory {
public Fruit trafficFruit();
}
//定义运送苹果类(TrafficApple)实现水果工厂(FruitFactory)接口
public class TrafficApple implements FruitFactory{
public Fruit trafficFruit() {
return new Apple();
}
}
//定义运送葡萄类(TrafficApple)实现水果工厂(FruitFactory)接口
public class TrafficGrape implements FruitFactory{
public Fruit trafficFruit() {
return new Grape();
}
}
//定义运送橙子类(TrafficApple)实现水果工厂(FruitFactory)接口
public class TrafficOrange implements FruitFactory{
public Fruit trafficFruit() {
return new Orange();
}
}
//客户类
public class Client {
public static void main(String[] args) {
TrafficApple traffic = new TrafficApple();
//开始运送苹果
traffic.trafficFruit().expressedJuice();
//调用橙子的expressedJuice()方法,用于榨苹果汁
}
}
测试结果:
从上面的代码可以看出,工厂模式的核心在于一个抽象工厂类,它允许许多具体类从抽象工厂类中继承其创建行为。
三、Abstract Factory 模式
Factory Method模式针对只是一种类别(Fruit),如果还要运送蔬菜就不行了。在这种情况下,必须用到下面将要介绍的Abstract Factory(抽象工厂模式)。
代码实现
//定义一个蔬菜(Vegetable)接口
public interface Vegetable {
public void grow();//蔬菜是种植的
public void cook();//蔬菜是用来烹调的
}
//定义冬瓜(WhiteGourd)类实现蔬菜接口
public class WhiteGourd implements Vegetable {
@Override
public void grow() {
System.out.println("种冬瓜");
}
@Override
public void cook() {
System.out.println("煮冬瓜");
}
}
//定义胡萝卜(Carrot)类实现蔬菜接口
public class Carrot implements Vegetable{
@Override
public void grow() {
System.out.println("种胡萝卜");
}
@Override
public void cook() {
System.out.println("煮胡萝卜");
}
}
//定义番茄(Tomato)类实现蔬菜接口
public class Tomato implements Vegetable {
@Override
public void grow() {
System.out.println("种番茄");
}
@Override
public void cook() {
System.out.println("煮番茄");
}
}
//定义运送工厂接口
public class TrafficFactory implements ITrafficFactory {
@Override
public Fruit trafficFruit(Fruit whichFruit) {
return whichFruit;
}
@Override
public Vegetable trafficVegetable(Vegetable whichVegetable) {
return whichVegetable;
}
}
//定义运送工厂(ITrafficFactory)类实现运送工厂接口(TrafficFactory)
public class TrafficFactory implements ITrafficFactory {
@Override
public Fruit trafficFruit(Fruit whichFruit) {
return whichFruit;
}
@Override
public Vegetable trafficVegetable(Vegetable whichVegetable) {
return whichVegetable;
}
}
//编写客户类
public class Client {
public static void main(String[] args) {
Fruit orange = new Orange();//橙子实例
Vegetable carrot= new Carrot();//胡萝卜实例
TrafficFactory factory = new TrafficFactory();//运送工厂实例
factory.trafficFruit(orange).expressedJuice();//运送橙子,榨橙子
factory.trafficVegetable(carrot).cook();//运送胡萝卜,煮胡萝卜
}
}
测试结果:
Abstract Factory 模式只需向客户端提供一个接口,使得客户端在不必指定运送农产品的具体类的情况下,创建多个类型中的产品对象。