文章目录

创建型模式

  工厂方法模式属于类的创建行模式又被称为多态工厂模式。工厂方法模式的意义在于定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中,核心工厂类将不在负责产品的创建,这昂核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口。

  简单工厂模式又叫静态工厂模式,由一个工厂决定创建出哪一种商品的实例。只要输入想要的产品代号,就会实例化合适的对象。

  这里举个简单的例子:
  小张开了一家面包店,根据客人的不同需求提供不同的面包,这里就有不同的面包师傅做不同的面包,这些个面包师傅(HoneyBread、BlackBread)等又归一个总师傅管理BreadMaker,也就是这些师傅的手艺都是继承自该师傅,这个厨房后台呢,就相当于一个工厂(IFactory),不同的种类就由不同的工厂(HoneyFactory)生产,工厂会根据需求将不同的种类产品分给不同种类的总师傅(PizzaMaker、BreadMaker),在由师傅分配任务给不同的制作师。上诉流程就将整个工厂模型的思路理清了。

简单工厂类:

package com.hust.SimpleFactory;
public class BreadFactory {
    public static BreadMaker MakeBread(int breadType){
         BreadMaker breadMaker = null;
        switch (breadType) {
        case 1:
            breadMaker = new BlackBread();
            break;
        case 2:
            breadMaker =  new HoneyBread();
            break;
        case 3:
            breadMaker =  new WhiteBread();
            break;
        default:
            break;
        }
        return breadMaker;
    }
}

总师傅:

package com.hust.SimpleFactory;
public class BreadMaker {
    public void GetBread(){
    //nothing
    }
}

不同的面包师傅:

package com.hust.SimpleFactory;
public class BlackBread extends BreadMaker {
    public void  GetBread() {
        System.out.println("做出黑面包");;
    }
}
public class HoneyBread extends BreadMaker {
    public void GetBread() {
        System.out.println("做出蜂蜜面包");
    }
}

商店前台:

public static void main(String args[]) {
    BreadMaker breadMaker;
    System.out.println("面包店开业!");
    System.out.println("开始制作黑面包");
    breadMaker = BreadFactory.MakeBread(1);
    breadMaker.GetBread();
    System.out.println("开始制作蜂蜜面包");
    breadMaker = BreadFactory.MakeBread(2);
    breadMaker.GetBread();
    System.out.println("开始制作白面包");
    breadMaker = BreadFactory.MakeBread(3);
    breadMaker.GetBread();
}

工厂模式:除了上诉内容外增加了一个总工厂负责类:

package com.hust.Factory;
import com.hust.AbstractFactory.PizzaMaker;
import com.hust.SimpleFactory.BreadMaker; 
public interface IFactory {
    BreadMaker createBread();
    PizzaMaker createPizza();
}

不同的工厂类:如果增加pizza这个产品,就在总工厂里增加一个函数负责pizza(这就是抽象工厂模式)

public class HoneyFactory implements IFactory {
    @Override
    public BreadMaker createBread() {
        return new HoneyBread();
    }
    @Override
    public PizzaMaker createPizza() {
        return new HoneyPizza();
    }
}
public class BlackFactory implements IFactory {
    @Override
    public BreadMaker createBread() {
        return new BlackBread();
    }
    @Override
    public PizzaMaker createPizza() {
        return new BlackPizza();
    }
 }

工厂模式时的柜台操作:

public static void main(String args[]) {
    BreadMaker breadMaker;
    System.out.println("面包店开业!");
    System.out.println("开始制作黑面包");
    IFactory breadFactory = new BlackBreadFactory();
    breadMaker = breadFactory.createBread();
    breadMaker.GetBread();
    System.out.println("开始制作蜂蜜面包");
    breadFactory = new HoneyBreadFactory();
    breadMaker = breadFactory.createBread();
    breadMaker.GetBread();
    system.out.println("开始制作蜂蜜pizza");
    breadFactory = new HoneyBreadFactory();
    PizzaMaker pizzaMaker = breadFactory.createPizza();
    pizzaMaker.GetPizza();
}

不同的产品的师傅:

public class PizzaMaker {
    public void  GetPizza() {
        //nothing
    }
}
public class HoneyPizza extends PizzaMaker {
    @Override
    public void GetPizza() {
    // TODO Auto-generated method stub
    System.out.println("做出蜂蜜披萨");
    }
}

  问题:假设小张有很多分店,每个分店有不同的柜台,那天小张决定将黑巧克力面包改成抹牛油的,在修改了工厂之后,必须相应的修改柜台的代码,级每一个申明过breadMaker和pizzaMaker的地方都要修改,那么工作量将恨大。这就体现了抽象模式的缺点,便于交换产品的同时,也需要改动产品声明过的地方。如何避免呢?一种方法就是根据前台用户的输入,使用if switch语句进行判断,但随着产品的增长,分支会越来越多。那么客户端还是需要大量的修改。另一种方法就是——反射。对客户端代码修改如下:

try {
    Class<?> c = Class.forName("HoneyBreadFactory");
    try {
        breadFactory = (IFactory) c.newInstance();
        pizzaMaker = breadFactory.createPizza();
        pizzaMaker.GetPizza();
    } catch (Exception e) {
            // TODO: handle exception
    }
} catch (ClassNotFoundException e) {
        // TODO: handle exception
}

这样就避免了分支的出现。
这里提到了三个工厂模式:简单工厂工厂方法抽象工厂。他们的优缺点如下:
工厂模式

文章目录