工厂模式

本文是学习java与模式后的总结!

一、简介

工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。

下面是使用工厂模式的两种情况:
1.在编码时不能预见需要创建哪种类的实例。
2.系统不应依赖于产品类实例如何被创建、组合和表达的细节

工厂模式的几种形态:
(1)简单工厂(Simple Factory)模式,又称静态工厂方法模式(Static Factory MethodPattern)。
(2)工厂方法(Factory Method)模式,又称多态性工厂(Polymorphic Factory)模式或虚拟构造子(Virtual Constructor)模式;
(3)抽象工厂(Abstract Factory)模式,又称工具箱(Kit 或Toolkit)模式。

二、简单工厂模式

来个例子,有一个农场公司,专门向市场销售各类水果。在这个系统里需要描述下列的水果:

葡萄 Grape
草莓 Strawberry
苹果 Apple
水果与其他的植物有很大的不同,就是水果最终是可以采摘食用的。那么一个自然的作法就是建立一个各种水果都适用的接口,以便与农场里的其他植物区分开。

//水果接口

public interface Fruit{
 //生长
 void grow();
 //收获
 void harvest();
 //种植
 void plant();
}

//苹果类

public class Apple implements Fruit{
 private int treeAge;
 public void grow(){
 log("Apple is growing...");
 }
 public void harvest(){
 log("Apple has been harvested.");
 }
 public void plant(){
 log("Apple has been planted.");
 }
 public static void log(String msg){
 System.out.println(msg);
 }
 public int getTreeAge(){
 return treeAge;
 }
 public void setTreeAge(int treeAge){
 this.treeAge = treeAge;
 }
}

其他的水果类与其类似,略了。。。

//果园园丁类

public class FruitGardener
{

    //静态工厂方法,返回值类型为水果接口类型
    public static Fruit factory(String which){
        if (which.equalsIgnoreCase("apple"))
        {
            return new Apple();
        }
        else if (which.equalsIgnoreCase("strawberry"))
        {
            return new Strawberry();
        }
        else if (which.equalsIgnoreCase("grape"))
        {
            return new Grape();
        }
    //这里如果没有对应的应该跑出异常,省略不写了。麻烦的,返回个空吧。嘿嘿 

    return null;
    }
}

好了,现在客户端只要调用园丁的静态工厂方法,水果就出来了。

//客户类

public class client{
 public static void main(String[] args) {
  Fruit a=FruitGardener.factory("grape");

  。。。。    

 }
}

简单工厂模式的结构

clip_image002

简单工厂模式的角色:
工厂类( Creator )角色:担任这个角色的是工厂方法模式的核心,含有与应用紧密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象,它往往由一个具体 Java 类实现。
抽象产品( Product )角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。抽象产品角色可以用一个 Java 接口或者 Java 抽象类实现。
具体产品( Concrete Product )角色:工厂方法模式所创建的任何对象都是这个角色的实例,具体产品角色由一个具体 Java 类实现。

简单工厂模式在某种程度上支持“开-闭”原则,但是支持的还不够,因为如果有新的产品加入到系统中,就要去修改工厂类,将必要的逻辑加入到工厂类中。由此引入了工厂方法模式。

三、工厂方法模式

在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建 的工作交给子类去做。这个核心类则成为了一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。这种进一步的抽象,使工厂方法模式可以用来允许系统在不修改具体工厂角色的情况下引进新的产品。

工厂方法模式的结构:

clip_image006

工厂方法模式涉及的角色:
抽象工厂( Creator )角色:担任这个角色的是工厂方法模式的核心,它是与应用程序无关的。任何在模式中创建对象的工厂类必须实现这个接口。在上面的系统中这个角色由 Java 接口 Creator 扮演;在实际的系统中,这个角色也常常使用抽象 Java 类实现。
具体工厂( Concrete Creator )角色:担任这个角色的是实现了抽象工厂接口的具体 Java 类。具体工厂角色含有与应用密切相关的逻辑,并且受到应用程序的调用以创建产品对象。在本系统中给出了两个这样的角色,也就是具体 Java ConcreteCreator1 ConcreteCreator2
抽象产品( Product )角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在本系统中,这个角色由 Java 接口 Product 扮演;在实际的系统中,这个角色也常常使用抽象 Java 类实现。
具体产品( Concrete Product )角色:这个角色实现了抽象产品角色所声明的接口。工厂方法模式所创建的每一个对象都是某个具体产品角色的实例。

 

来个小例子。

public interface Moveable {
 //产品抽象类角色
 public void run();
}

public class Car implements Moveable{
 //具体产品类角色1
 public void run(){
  System.out.println("冒着烟奔跑run........");
 }
}

public class Plane implements Moveable {
 //具体产品类角色2
 public void run() {
  System.out.println("扇着翅膀奔跑plane");
 }
}

public interface VehicleFactory {
 //抽象工厂类角色
 Moveable creat();
}

public class CarFactory implements VehicleFactory{
 //具体工厂类角色1
 public Moveable creat() {
  return new Car();
 }
}

public class PlaneFactory implements VehicleFactory{
 //具体工厂类角色2
 public Moveable creat() {
  return new Plane();
 }
}

//客户类

public class client{
 public static void main(String[] args) {
  //VehicleFactory v=new CarFactory();
  VehicleFactory v=new PlaneFactory();
  v.creat().run();
 }
}

在工厂方法模式中,如果系统需要加入一个新产品,那么所需要的就是向系统中加入一个这个产品类以及它对应的工厂类,没必要修改抽象工厂角色或其他具体工厂角色,对于新增产品类而言,这个系统完全支持“开-闭”原则。

四、抽象工厂模式

 工厂方法模式与抽象工厂方法的最大区别在于工厂方法是针对一个产品的,而抽象工厂针对的是一系列的产品。

例子如下:

//抽象工厂

public abstract class AbstractFactory {
  //生产车辆

   public abstract Vehicle createVehicle();
  //生产武器

   public abstract Weapon createWeapon();
  //生产实物

  public abstract Food createFood();
}

//具体工厂类角色(魔法工厂)

public class MagicFactory extends AbstractFactory {
 public Food createFood() {
  return new MushRoom();
 }
 public Vehicle createVehicle() {
  return new Broom();
 }
 public Weapon createWeapon() {
  return new MagicStick();
 }
}

//具体工厂类角色(普通工厂)

public class DefaultFactory extends AbstractFactory{
 public Food createFood() {
  return new Apple();
 }
 public Vehicle createVehicle() {
  return new Car();
 }
 public Weapon createWeapon() {
  return new AK47();
 }
}

//抽象产品类1

public abstract class Vehicle {
 public abstract void run();
}

//抽象产品类2

public abstract class Weapon {
 public abstract void shoot();
}

//抽象产品类3

public abstract class Food {
 public abstract void printName();
}

//具体产品类1

public class Car extends Vehicle {
 public void run() {
  System.out.println("冒着烟奔跑中car.......");
 }
}

//具体产品类2

public class AK47 extends Weapon{
 public void shoot() {
  System.out.println("哒哒哒...");
 }
}

//具体产品类3

public class Apple extends Food {
 public void printName() {
  System.out.println("apple");
 }
}

//客户类

public class client{
 public static void main(String[] args) {
  AbstractFactory f = new DefaultFactory();
  Vehicle v = f.createVehicle();
  v.run();
  Weapon w = f.createWeapon();
  w.shoot();
  Food a = f.createFood();
  a.printName();
 }
}

一个抽象工厂对应的是一系列的抽象产品。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值