前言

在前面的章节中,我们先后介绍了简单工厂模式和工厂方法模式。他们都是工厂模式大家族的一员,那么,本章将会接着上一章,来说一说工厂模式的最后一员,那就是抽象工厂模式。

思考题

首先,来思考下下面的问题怎么实现:

在工厂方法模式中,博主在四川和上海开了一家饭店,目前生意相当的火爆,但是还是不赚钱。分析原因发现,目前各家分店都是自己采购原料,并且很贵。那博主就不愿意了,博主决定,自己开一家生产原料的工厂。那么我们应该去实现这个工厂呢?

要是学习了 抽象工厂模式 ,你就会很惊喜的发现,那家伙可以很好的满足我们的需求。

抽象工厂模式

定义:抽象工厂模式就是在抽象工厂中提供一系列的接口,用这一系列的接口创建相关或者依赖对象的家族,而不需要指定具体的类。

类图:

上面的类图,涉及以下几个角色:

  • 抽象产品A,B:为产品A,B定义了一些接口。
  • 具体产品A,B:抽象产品A,B的具体实现。
  • 抽象工厂:定义了一些列的接口,用于创建具体的产品A,B。
  • 具体工厂:实现了抽象工厂的一系列接口,可以生产一些相关的产品。

思考题实现

首先,定义抽象产品:

Salt.java:

public interface Salt {
String put();
}

然后,定义抽象产品的实现:

ShangHaiSalt.java:

public class ShangHaiSalt implements Salt {
public String put() {
return "上海的盐";
}
}

SiChuanSalt.java:

public class SiChuanSalt implements Salt {
public String put(){
return "四川的盐";
}
}

然后,定义抽象原料工厂:

IngredientFactory.java:

public interface IngredientFactory {
Salt createSalt();
}

然后,实现抽象原料工厂:

ShangHaiIngredientFactory.java:

public class ShangHaiIngredientFactory implements IngredientFactory {
public Salt createSalt() {
return new ShangHaiSalt();
}
}

SiChuanIngredientFactory.java:

public class SiChuanIngredientFactory implements IngredientFactory {
public Salt createSalt() {
return new SiChuanSalt();
}
}

然后,定义抽象产品:

Food.java:

public abstract class Food {
protected IngredientFactory ingredientFactory; public Food(IngredientFactory ingredientFactory) {
this.ingredientFactory = ingredientFactory;
} public void fry() {
System.out.println("翻炒");
} public void eat() {
System.out.println("吃");
} public abstract void putSeasoning();
}

然后,实现抽象产品:

KungPaoChicken.java:

public class KungPaoChicken extends Food {
public KungPaoChicken(IngredientFactory ingredient) {
super(ingredient);
} @Override
public void putSeasoning() {
Salt salt = ingredientFactory.createSalt();
System.out.println("放入" + salt.put());
}
}

TomatoEgg.java:

public class TomatoEgg extends Food {

    public TomatoEgg(IngredientFactory ingredientFactory) {
super(ingredientFactory);
}
@Override
public void putSeasoning() {
Salt salt = ingredientFactory.createSalt();
System.out.println("放入" + salt.put());
}
}

然后,定义抽象工厂:

AbstractHotal.java:

public abstract class AbstractHotal {
public Food saleFood(String foodName) {
Food food = createFood(foodName);
food.putSeasoning();
food.fry();
return food;
} public abstract Food createFood(String foodName);
}

然后,实现抽象工厂:

ShangHaiHotal.java:

public class ShangHaiHotal extends AbstractHotal {
@Override
public Food createFood(String foodName) {
IngredientFactory ingredient = new ShangHaiIngredientFactory();
switch(foodName) {
case "KungPaoChicken":
return new KungPaoChicken(ingredient);
case "TomatoEgg":
return new TomatoEgg(ingredient);
default:
return null;
}
}
}

SiChuanHotal.java:

public class SiChuanHotal extends AbstractHotal {
@Override
public Food createFood(String foodName) {
IngredientFactory ingredient = new SiChuanIngredientFactory();
switch(foodName) {
case "KungPaoChicken":
return new KungPaoChicken(ingredient);
case "TomatoEgg":
return new TomatoEgg(ingredient);
default:
return null;
}
}
}

最后附上测试代码:

Custom.java:

public class Custom {
public static void main(String ...args) {
AbstractHotal shangHaiHotal = new ShangHaiHotal();
AbstractHotal siChuanHotal = new SiChuanHotal(); Food shangHaiKungPaoChicken = shangHaiHotal.saleFood("KungPaoChicken");
Food shangHaiTomatoEgg = shangHaiHotal.saleFood("TomatoEgg"); Food siChuanKungPaoChicken = siChuanHotal.saleFood("KungPaoChicken");
Food siChuanTomatoEgg = siChuanHotal.saleFood("TomatoEgg"); shangHaiKungPaoChicken.eat();
shangHaiTomatoEgg.eat(); siChuanKungPaoChicken.eat();
siChuanTomatoEgg.eat();
}
}

[design pattern](6) Absract Factory的更多相关文章

  1. [design pattern](4) SImple Factory

    前言 本博客主要介绍简单工厂模式(Simple Factory),简单工厂模式是创建型模式的一员,也是我们平时coding用到的比较多的一个模式了. 思考题 首先,让我们思考以下的需求: 博主,突然很 ...

  2. [Design Pattern] Factory Pattern 简单案例

    Factory Pattern , 即工厂模式,用于创建对象的场景,属于创建类的设计模式 . 下面是一个工厂模式案例. Shape 作为接口, Circle, Square, Rectangle 作为 ...

  3. 简单工厂设计模式(Simple Factory Design Pattern)

    [引言]最近在Youtub上面看到一个讲解.net设计模式的视频,其中作者的一个理解让我印象很深刻:所谓的设计模式其实就是运用面向对象编程的思想来解决平时代码中的紧耦合,低扩展的问题.另外一点比较有见 ...

  4. 说说设计模式~大话目录(Design Pattern)

    回到占占推荐博客索引 设计模式(Design pattern)与其它知识不同,它没有华丽的外表,没有吸引人的工具去实现,它是一种心法,一种内功,如果你希望在软件开发领域有一种新的突破,一个质的飞越,那 ...

  5. 设计模式(Design Pattern)系列之.NET专题

    最近,不是特别忙,重新翻了下设计模式,特地在此记录一下.会不定期更新本系列专题文章. 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 使用 ...

  6. [转]Design Pattern Interview Questions - Part 4

    Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, COR Pattern, Proxy Pattern, te ...

  7. [转]Design Pattern Interview Questions - Part 1

    Factory, Abstract factory, prototype pattern (B) What are design patterns? (A) Can you explain facto ...

  8. C++ Design Pattern: What is a Design Pattern?

    Q: What is a Design Pattern? A: Design Patterns represent solutions to problems what arise when deve ...

  9. Design Pattern in Simple Examples

    Instead of defining what is design pattern lets define what we mean by design and what we mean by pa ...

随机推荐

  1. WAMP中的mysql设置密码

    为WAMP中的mysql设置密码密码 WAMP安装好后,mysql密码是为空的,那么要如何修改呢?其实很简单,通过几条指令就行了,下面我就一步步来操作. 1.首先,通过WAMP打开mysql控制台. ...

  2. 【Linux】C字节对齐

    原文地址:https://www.jianshu.com/p/e8fcc01041a7 什么是对齐,以及为什么要对齐: 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问 ...

  3. 前端页面适配的rem换算 为什么要使用rem

    之前有些适配做法,是通过js动态计算viewport的缩放值(initial-scale). 例如以屏幕320像素为基准,设置1,那屏幕375像素就是375/320=1.18以此类推. 但直接这样强制 ...

  4. python图形图像处理--验证码的制作

    from PIL import Image,ImageDraw,ImageFontimport randomfrom io import BytesIO class code(): def __ini ...

  5. 在vue的js文件引入自定义js文件

    自定义js var provinces=[] export default provinces vue页面js引入 import riskLeft from "./index.js" ...

  6. layui ri laydate的常规使用,并且日期最大不能超过当前日期

    laydate的常规使用,分为两种方式实现日期组件 一.在 layui 模块中使用 下载layui   地址 :https://www.layui.com/  引入资源路径 js 和 css 通过下面 ...

  7. hier - 文件系统描述

    DESCRIPTION 描述 一个典型的Linux系统具有以下几个目录: / 根目录,是所有目录树开始的地方. /bin 此目录下包括了单用户方式及系统启动或修复所用到的所有执行程序. /boot 包 ...

  8. centos7进入单用户模式修改root密码

    1.开机 按“e”,然后输入init=/bin/sh 2.根据提示按ctrl+x 得如下图: 3.输入mount -o remount,rw    /  输入passwd设置新密码.如下图:  4.输 ...

  9. SpringBootMVC01——A simple SpringBootMVC Sample

    不带数据库的SpringBootMVC案例 1.创建一个SpringBoot项目,添加thymeleaf,webstarter 2.目录层级 3.启动器代码 package com.littlepag ...

  10. [易学易懂系列|rustlang语言|零基础|快速入门|(12)|Enums枚举]

    [易学易懂系列|rustlang语言|零基础|快速入门|(12)] 有意思的基础知识 Enums 今天我们来讲讲枚举. 在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者 ...