工厂方法模式
工厂方法(FactoryMethod)模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。
1. 模式的结构
工厂方法模式的主要角色如下。
- 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
- 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
package FactoryMethod;
public class AbstractFactoryTest
{
public static void main(String[] args)
{
try
{
Product a;
AbstractFactory af;
af=(AbstractFactory) ReadXML1.getObject();
a=af.newProduct();
a.show();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
//抽象产品:提供了产品的接口
interface Product
{
public void show();
}
//具体产品1:实现抽象产品中的抽象方法
class ConcreteProduct1 implements Product
{
public void show()
{
System.out.println("具体产品1显示...");
}
}
//具体产品2:实现抽象产品中的抽象方法
class ConcreteProduct2 implements Product
{
public void show()
{
System.out.println("具体产品2显示...");
}
}
//抽象工厂:提供了厂品的生成方法
interface AbstractFactory
{
public Product newProduct();
}
//具体工厂1:实现了厂品的生成方法
class ConcreteFactory1 implements AbstractFactory
{
public Product newProduct()
{
System.out.println("具体工厂1生成-->具体产品1...");
return new ConcreteProduct1();
}
}
//具体工厂2:实现了厂品的生成方法
class ConcreteFactory2 implements AbstractFactory
{
public Product newProduct()
{
System.out.println("具体工厂2生成-->具体产品2...");
return new ConcreteProduct2();
}
}
工厂方法模式通常适用于以下场景。
- 客户只知道创建产品的工厂名,而不知道具体的产品名。如 TCL 电视工厂、海信电视工厂等。
- 创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
- 客户不关心创建产品的细节,只关心产品的品牌。
当需要生成的产品不多且不会增加,一个具体工厂类就可以完成任务时,可删除抽象工厂类。这时工厂方法模式将退化到简单工厂模式。
抽象工厂模式
工厂方法模式中考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机、计算机软件学院只培养计算机软件专业的学生等。
抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
使用抽象工厂模式一般要满足以下条件。
- 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
- 系统一次只可能消费其中某一族产品,即同族的产品一起使用。
抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下。
- 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
- 当增加一个新的产品族时不需要修改原代码,满足开闭原则。
其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。
public class Test {
public static void main(String[] args) {
//只需要替换new 的具体factory就可以实现系列产品的替换
//在扩展的时候,如果需要添加新的系列产品只需要继承对应的抽象类即可完成扩产
//将new MagicFactory()提取为从配置文件中读取,可以实现不修改代码实现工厂的切换
AbstractFactory f = new MagicFactory();
Vehicle v = f.createVehicle();
Weapon v = f.createWeapon();
Food v = f.createFood();
}
}
//抽象工厂
public abstract class AbstractFactory {
public abstract Vehicle createVehicle();
public abstract Weapon createWeapon();
public abstract Food createFood();
}
//工厂实现一,生产对应系列产品
public abstract DefaultFactory extends AbstractFactory {
@Override
public Vehicle createVehicle() {
return new Car();
}
@Override
public Weapon createWeapon() {
return new AK47();
}
@Override
public Food createFood() {
return new Apple();
}
}
//工厂实现二,生产对应系列产品
public abstract MagicFactory extends AbstractFactory {
@Override
public Vehicle createVehicle() {
return new Broom();
}
@Override
public Weapon createWeapon() {
return new MagicStick();
}
@Override
public Food createFood() {
return new MushRoom();
}
}
//Vehicle产品抽象
public abstract class Vehicle {
public abstract void run();
}
//Vehicle产品,具体产品一
public class Car extends Vehicle {
@override
public void run() {
System.out.println("Car run...");
}
}
//Vehicle产品,具体产品二
public class Broom extends Vehicle {
@override
public void run() {
System.out.println("Broom fly...");
}
}
//Weapon产品抽象
public abstract class Weapon {
public abstract void shoot();
}
//Weapon产品,具体产品一
public class Ak47 extends Weapon {
@override
public void shoot() {
System.out.println("Ak47 Shoot...");
}
}
//Weapon产品,具体产品二
public class MagicStick extends Weapon {
@override
public void shoot() {
System.out.println("MagicStick Shoot...");
}
}
//Food产品抽象
public abstract class Food {
public abstract void printName();
}
//Food产品,具体产品一
public class Apple extends Food {
@override
public String getName() {
System.out.println("Apple...");
}
}
//Food产品,具体产品二
public class MushRoom extends Food {
@override
public String getName() {
System.out.println("MushRoom...");
}
}