王小抠活成了工厂的样子

NEW 自食其力

王小扣在早上 7 点准时床,第一件事情就是要作一顿早餐补充下能量。王小扣的早餐是一个手抓饼(此处省略作手抓饼的简单过程)本身作上本身吃,很美味。java

代码实现:
早餐能够包含的食物不少,咱们抽象为 Food 接口。
手抓饼是具体的产品,咱们定义为 ShouZhuaBing 类。git

public class OldTest {
    public static void main(String[] args) {
        Food shouZhuaBing = new ShouZhuaBing();
        shouZhuaBing.eaten();
    }
}

简单工厂 和别人要

吃完早餐的王小抠正要去上班,这个时候刚刚睡醒的女票叫住了他:
“王小扣,我饿了。。”
“拜拜,我去上班了”
“王小扣,我要吃手抓饼!!”
“哦,那我再作一个呗”
这个时候,王小抠意识到本身变成了一个失去理智温顺善良的简单工厂,女票和他要手抓饼他就马上去作,不让女票关心手抓饼如何去作。web

代码实现:
咱们把王小抠抽象为一个简单工厂类 SimpleFactory
把使唤工厂的女票抽象为类 SimpleFactoryUseride

// 定义简单工厂类
public class SimpleFactory {
	// 定义静态工厂方法
    public static Food createFood(String foodName) {
        Food food = null;
        if ("手抓饼".equals(foodName)) {
            food = new ShouZhuaBing();
        } else if ("其它食物。。。".equals(foodName)) {
            // food = new XXX
        }
        return food;
    }
}
public class SimpleFactoryUser {
    public static void main(String[] args) {
        Food shouZhuaBing = SimpleFactory.createFood("手抓饼");
        shouZhuaBing.eaten();
    }
}
// 手抓饼被吃了!

能够看出简单工厂的优势是,使用者能够直接从工厂中拿到想要的产品,而不用了解产品的生产过程。
因为 createFood 的修饰符为 static ,因此简单工厂又叫静态工厂。svg

工厂方法 建立分身

日子一每天过去,王小抠的生活愈来愈痛苦了,由于女票吃腻了手抓饼,开始和王小抠要烤冷面、鸡蛋灌饼。。。
但是王小抠以为作两样早餐有点费时间呀,又得早起十分钟呢。
这个时候王小抠就幻想着能有一个会作烤冷面的分身,再来一个会作鸡蛋灌饼的分身,再来一个。。。
这样可让每一个王小抠负责每种早餐的制做,咱们想吃什么只须要找相应的王小抠便可。spa

代码实现:
每一个分身王小抠都是一个具体的工厂,他们都拥有制做早餐的方法。
这样咱们就能够定义一个抽象接口 Factory 和 抽象的工厂方法 createFood。code

// 定义接口
public interface Factory {
	// 定义工厂方法
    Food createFood();
}
// 定义具体工厂类
public class KaoLengMianFactory implements Factory{
    public Food createFood() {
        return new KaoLengMian();
    }
}
public class ShouZhuaBingFactory implements Factory{
    public Food createFood() {
        return new ShouZhuaBing();
    }
}
// 使用
public class FactoryMethodTest {
    public static void main(String[] args) {
        KaoLengMianFactory kaoLengMianFactory = new KaoLengMianFactory();
        Food kaoLengMian = kaoLengMianFactory.createFood();
        kaoLengMian.eaten();

        ShouZhuaBingFactory shouZhuaBingFactory = new ShouZhuaBingFactory();
        Food shouZhuaBing = shouZhuaBingFactory.createFood();
        shouZhuaBing.eaten();
    }
}
// 烤冷面被吃了!
// 手抓饼被吃了!

工厂方法能够看出是简单工厂的升级,简单工厂把不一样种类产品的建立都放到一个类的一个方法中。
如今咱们将建立产品的工做放到不一样类中,有多少产品就建立多少工厂,让工厂的功能更加专注。
在获取产品时,使用者须要指定具体的工厂,仍然有耦合,请忽略,使用工厂的目的是对产品建立工做的解耦xml

抽象工厂 不一样配方

分身太多,记不住呀能不能统一管理呀。token

// 建立抽象工厂
public abstract class AbstractFactory {
	
	// TODO

    abstract Food createShouZhuangbing();

    abstract Food createKaoLengMian();
}
// 具体实现
public class Factory extends AbstractFactory {
    @Override
    Food createShouZhuangbing() {
        return new ShouZhuaBing();
    }

    @Override
    Food createKaoLengMian() {
        return new KaoLengMian();
    }
}
// 使用
public class AbstractFactoryUser {
    public static void main(String[] args) {
        AbstractFactory factory = new Factory();
        Food kaoLengMian = factory.createKaoLengMian();
        Food shouZhuangbing = factory.createShouZhuangbing();

        kaoLengMian.eaten();
        shouZhuangbing.eaten();
    }
}

抽象工厂只须要获取一个工厂,经过工厂的不一样方法就能够建立不一样的产品。接口

新增产品时

  1. 静态工厂须要修改代码,增长 if 语句
  2. 工厂方法须要增长新的类,在使用处还须要 new 一个新的工厂
  3. 抽象工厂须要在 AbstractFactory 和 Factory 中添加方法,仍是用原来的 factory 去建立

以上只是说了抽象工厂能够对不一样产品进行统一管理,和不一样配方没有多大联系。
想要实现不一样配方,须要再建立几个抽象工厂的实现类。

// 甜味的早餐
public class TianFactory extends AbstractFactory{
}
// 辣味的早餐
public class LaFactory extends AbstarctFactory{
}

若是咱们要吃甜味的,只要使用甜味工厂,建立出的全部产品都是甜味的

AbstractFactory factory = New TianFactory();
factory.createXXX

完整代码