正文

一、定义

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

要点:

  • 抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道实际产品的具体产品是什么。这样一来,客户就从具体的产品中被解耦。
  • 抽象工厂的任务是定义一个负责创建一组产品的接口。这个接口内的每个方法都负责创建一个产品,同时利用实现抽象工厂的子类来提供具体的做法。
  • 抽象工厂的方法经常以工厂方法的方式实现。

二、实现步骤

1、创建产品抽象类

(1)产品A抽象类

/**
* 产品A抽象类
*/
public abstract class ProductA { String name; public String getName() {
return name;
}
}

(2)产品B抽象类

/**
* 产品B抽象类
*/
public abstract class ProductB { String name; public String getName() {
return name;
}
}

2、创建具体的产品,并继承产品抽象类

(1)产品A1

/**
* 产品A1
*/
public class ConcreteProductA1 extends ProductA { public ConcreteProductA1() {
name = "ConcreteProductA1";
}
}

(2)产品A2

/**
* 产品A2
*/
public class ConcreteProductA2 extends ProductA { public ConcreteProductA2() {
name = "ConcreteProductA2";
}
}

(3)产品B1

/**
* 产品B1
*/
public class ConcreteProductB1 extends ProductB { public ConcreteProductB1() {
name = "ConcreteProductB1";
}
}

(4)产品B2

/**
* 产品B2
*/
public class ConcreteProductB2 extends ProductB { public ConcreteProductB2() {
name = "ConcreteProductB2";
}
}

3、创建工厂接口,并定义创建产品的方法

也可以使用工厂抽象类,然后在创建具体工厂时继承工厂抽象类。

/**
* 抽象工厂接口
*/
public interface AbstractFactory { /**
* 创建产品A
*/
public ProductA createProductA(); /**
* 创建产品B
*/
public ProductB createProductB();
}

4、创建具体的工厂,并实现工厂接口

(1)工厂1

/**
* 工厂1
*/
public class ConcreteFactory1 implements AbstractFactory { @Override
public ProductA createProductA() {
return new ConcreteProductA1();
} @Override
public ProductB createProductB() {
return new ConcreteProductB1();
}
}

(2)工厂2

/**
* 工厂2
*/
public class ConcreteFactory2 implements AbstractFactory { @Override
public ProductA createProductA() {
return new ConcreteProductA2();
} @Override
public ProductB createProductB() {
return new ConcreteProductB2();
}
}

5、使用工厂创建产品

public class Test {

    public static void main(String[] args) {
// 工厂1
AbstractFactory factory1 = new ConcreteFactory1();
// 工厂2
AbstractFactory factory2 = new ConcreteFactory2(); // 工厂1创建产品
ProductA productA = factory1.createProductA();
System.out.println("工厂1创建产品A:" + productA.getName());
ProductB productB = factory1.createProductB();
System.out.println("工厂1创建产品B:" + productB.getName());
// 工厂2创建产品
productA = factory2.createProductA();
System.out.println("工厂2创建产品A:" + productA.getName());
productB = factory2.createProductB();
System.out.println("工厂2创建产品B:" + productB.getName());
}
}

三、举个栗子

1、背景

假设你有一个披萨店,并且拥有许多加盟店。为了确保每家加盟店都能使用高质量的原料,你打算建造生产原料的工厂,并将原料运送到各家加盟店。

由于加盟店坐落在不同的区域,每个区域的原料是不一样的。因此,必须能够针对不同的区域提供相应的原料。

2、实现

为每个区域建造一个工厂,每个工厂负责创建相应区域的原料。

(1)创建所有原料抽象类

/**
* 面团抽象类
*/
public abstract class Dough { String name; public String getName() {
return name;
}
}
/**
* 酱料抽象类
*/
public abstract class Sauce { String name; public String getName() {
return name;
}
}
/**
* 芝士抽象类
*/
public abstract class Cheese { String name; public String getName() {
return name;
}
}

(2)创建不同区域的所有原料

/**
* 薄皮面团
*/
public class ThinCrustDough extends Dough { public ThinCrustDough() {
name = "Thin Crust Dough";
}
}
/**
* 厚皮面团
*/
public class ThickCrustDough extends Dough { public ThickCrustDough() {
name = "Thick Crust Dough";
}
}
/**
* 大蒜番茄酱
*/
public class MarinaraSauce extends Sauce { public MarinaraSauce() {
name = "Marinara Sauce";
}
}
/**
* 番茄酱
*/
public class PlumTomatoSauce extends Sauce { public PlumTomatoSauce() {
name = "Plum Tomato Sauce";
}
}
/**
* 帕马森雷加诺干酪
*/
public class ReggianoCheese extends Cheese{ public ReggianoCheese() {
name = "Reggiano Cheese";
}
}
/**
* 马苏里拉奶酪
*/
public class MozzarellaCheese extends Cheese{ public MozzarellaCheese() {
name = "Mozzarella Cheese";
}
}

(3)创建原料工厂接口

/**
* 披萨原料工厂接口
*/
public interface PizzaIngredientFactory { /**
* 创建面团
*/
public Dough createDough(); /**
* 创建酱料
*/
public Sauce createSauce(); /**
* 创建芝士
*/
public Cheese createCheese(); // 创建其他原料
}

(4)创建不同区域的原料工厂

/**
* 纽约原料工厂
*/
public class NYPizzaIngredientFactory implements PizzaIngredientFactory { @Override
public Dough createDough() {
return new ThinCrustDough();
} @Override
public Sauce createSauce() {
return new MarinaraSauce();
} @Override
public Cheese createCheese() {
return new ReggianoCheese();
}
}
/**
* 芝加哥原料工厂
*/
public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory { @Override
public Dough createDough() {
return new ThickCrustDough();
} @Override
public Sauce createSauce() {
return new PlumTomatoSauce();
} @Override
public Cheese createCheese() {
return new MozzarellaCheese();
}
}

(5)使用不同区域的原料工厂创建原料

public class Test {

    public static void main(String[] args) {
// 纽约原料工厂
PizzaIngredientFactory nyFactory = new NYPizzaIngredientFactory();
// 芝加哥原料工厂
PizzaIngredientFactory chicagoFactory = new ChicagoPizzaIngredientFactory(); // 使用纽约原料工厂创建原料
Dough dough = nyFactory.createDough();
Sauce sauce = nyFactory.createSauce();
Cheese cheese = nyFactory.createCheese();
System.out.println("New York Pizza Ingredient Factory Create:");
System.out.println(" " + dough.getName());
System.out.println(" " + sauce.getName());
System.out.println(" " + cheese.getName() + "\n");
// 使用芝加哥原料工厂创建原料
dough = chicagoFactory.createDough();
sauce = chicagoFactory.createSauce();
cheese = chicagoFactory.createCheese();
System.out.println("Chicago Pizza Ingredient Factory Create:");
System.out.println(" " + dough.getName());
System.out.println(" " + sauce.getName());
System.out.println(" " + cheese.getName());
}
}

《Head First 设计模式》:抽象工厂模式的更多相关文章

  1. 《Android源码设计模式》--Builder模式

    No1: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 No2: 在Android源码中,最常用到的Builder模式就是AlertDialog.Builder No3: ...

  2. 《Android源码设计模式》--工厂方法模式

    No1: 对于一个应用程序来说,其真正的入口是在ActivityThread类中,ActivityThread中含有我们熟悉的main方法.ActivityThread是一个final类,不能被继承. ...

  3. 《Android源码设计模式》--状态模式--责任链模式--解释器模式--命令模式--观察者模式--备忘录模式--迭代器模式

    [状态模式] No1: Wifi设置界面是一个叫做WifiSetting的Fragment实现的 No2: 在不同的状态下对于扫描Wifi这个请求的处理是完全不一样的.在初始状态下扫描请求被直接忽略, ...

  4. 《Android源码设计模式》--模板方法模式

    No1: 模板方法模式包括:抽象类(其中定义了一系列顺序方法).具体实现类A.具体实现类B 如果子类有实现不一样的细节,重写父类的某个方法即可 No2: AsyncTask对象调用execute方法后 ...

  5. 《Android源码设计模式》--策略模式

    No1: 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. No2: 使用场景: 1)针对同一类型问题的多种处理方式,仅 ...

  6. 《Android源码设计模式》--原型模式

    No1: 原型模式使用场景: 1)类初始化需要消耗非常多的资源,这个资源包括数据.硬件资源等,通过原型复制避免这些消耗 2)通过new产生一个对象需要非常繁琐的数据准备货访问权限,这是可以使用原型模式 ...

  7. 《Android源码设计模式》学习笔记之ImageLoader

    微信公众号:CodingAndroid cnblog:http://www.cnblogs.com/angel88/ CSDN:http://blog.csdn.net/xinpengfei521 需 ...

  8. 设计模式——抽象工厂模式及java实现

    设计模式--抽象工厂模式及java实现 设计模式在大型软件工程中很重要,软件工程中采用了优秀的设计模式有利于代码维护,方便日后更改和添加功能. 设计模式有很多,而且也随着时间在不断增多,其中最著名的是 ...

  9. 5. 星际争霸之php设计模式--抽象工厂模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  10. 《Android源码设计模式》--抽象工厂模式

    No1: 4种MediaPlayer Factory分别会生成不同的MediaPlayer基类:StagefrightPlayer.NuPlayerDriver.MidiFile和TestPlayer ...

随机推荐

  1. 比Minikube更快,使用Kind快速创建K8S学习环境

    简述 K8S 如火如荼的发展着,越来越多人想学习和了解 K8S,但是由于 K8S 的入门曲线较高很多人望而却步. 然而随着 K8S 生态的蓬勃发展,社区也呈现了越来越多的部署方案,光针对生产可用的环境 ...

  2. django项目常见报错集

    1.mysqlclient 目前不支持高版本python3 django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or new ...

  3. MySQL 百万级数据量分页查询方法及其优化

    方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N 适应场景: 适用于数据量较少的情况(元组百/千级) 原因/缺 ...

  4. [Python] list vs tupple

    前言 列表(list)和 元组(tupple) 是 Python 中常见的两种数据结构.这两者使用方法有一定的相似,俩者都是 Python 内置类型,都可以保存数据集合,都可以保存复合数据,我们同样可 ...

  5. css实现1px 像素线条_解决移动端1px线条的显示方式

    使用CSS 绘制出 1px 的边框,在移动端上渲染的效果会出现不同,部分手机发现1px 线条变胖了,这篇文章整理2种方式实现1px 像素线条. 1.利用box-shadow + transform & ...

  6. Tensorflow教程(3)什么是张量?什么是数据流图?

    Tensorflow = Tensor(张量) + flow(数据流图) 1.张量 张量可不是“麻辣烫”!张量是一个很抽象的概念,直观的来说,张量在tensorflow中就像一个杯子,起到保存数据的作 ...

  7. 奇怪DP之步步为零

    题目 思路 很明显的dp就是不会跑啊,所以最后dfs救了一下场,不出所料,最后果然T了,现在说一下正解. 为什么说是奇怪dp呢,这道题的dp数组是布尔型的,f[i][j][k]代表在到第i行第j列之前 ...

  8. 返回报文变成xml格式了!

    首先,google chrome之前有安装jsonview插件: 然后,自己弄springCloud项目,搭建eureka后,访问url发现返回报文变成xml格式了,一通摸索及查找,现整理如下: 1. ...

  9. sql语句replace函数的使用

    SQL中的替换函数replace()使用 语法 REPLACE ( string_expression , string_pattern , string_replacement ) 参数 strin ...

  10. Python-日期格式化

    1.基本方法 获取当前日期:time.time() 获取元组形式的时间戳:time.local(time.time()) 格式化日期的函数(基于元组的形式进行格式化): (1)time.asctime ...