Java使用抽象工厂模式实现的肯德基消费案例详解

本文实例讲述了Java使用抽象工厂模式实现的肯德基消费案例。分享给大家供大家参考,具体如下:

一、模式定义

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

抽象工厂模式允许客户使用抽象接口来创建一组相关的产品,客户类和工厂类分开,客户需要任何产品的时候,只需要向工厂请求即可,客户无须修改就可以获得新产品。

二、模式举例

1 模式分析

我们借用爸爸和儿子到肯德基店消费这一场景来说明这一模式,进行抽象分析后的截图如下

2 抽象工厂模式的静态建模

3 代码示例

3.1 抽象食物的建立

抽象食物——AbstractBaseFood

package com.demo.factory.model;
/**
 *
 * 食物基类
 *
 * @author maofw
 *
 */
public abstract class AbstractBaseFood
{
  // 类别
  protected String kind;
  // 数量
  protected int num;
  // 价格
  protected float price;
  // 合计
  public float totalPrice()
  {
    return this.num * this.price;
  }
}

食物接口——IFood

package com.demo.factory.model;
/**
 * 抽象食物接口
 *
 * @author maofw
 *
 */
public interface IFood
{
  /**
   * 打印输出食物信息
   */
  void printMesage();
}

3.2 建立不同食物的抽象基类

汉堡基类——Hamburg

package com.demo.factory.model;
/**
 * 汉堡基类
 *
 * @author maofw
 *
 */
public abstract class Hamburg extends AbstractBaseFood implements IFood
{
  public void printMesage()
  {
    System.out.println("--" + this.kind + "风味汉堡,\t单价:" + this.price + ",\t数量:" + this.num + ",\t合计:" + this.totalPrice());
  }
}

鸡翅基类——ChickenWings

package com.demo.factory.model;
/**
 * 鸡翅基类
 *
 * @author maofw
 *
 */
public abstract class ChickenWings extends AbstractBaseFood implements IFood
{
  public void printMesage()
  {
    System.out.println("--" + this.kind + "风味鸡翅,\t单价:" + this.price + ",\t数量:" + this.num + ",\t合计:" + this.totalPrice());
  }
}

薯条基类——FrenchFries

package com.demo.factory.model;
/**
 * 薯条基类
 *
 * @author maofw
 *
 */
public abstract class FrenchFries extends AbstractBaseFood implements IFood
{
  public void printMesage()
  {
    System.out.println("--" + this.kind + "风味薯条,\t单价:" + this.price + ",\t数量:" + this.num + ",\t合计:" + this.totalPrice());
  }
}

饮料基类——Beverage

package com.demo.factory.model;
/**
 * 饮料基类
 *
 * @author maofw
 *
 */
public abstract class Beverage extends AbstractBaseFood implements IFood
{
  public void printMesage()
  {
    System.out.println("--" + this.kind + "饮料,\t单价:" + this.price + ",\t数量:" + this.num + ",\t合计:" + this.totalPrice());
  }
}

3.3 创建具体的食物

麻辣鸡腿汉堡——ChinaHanburm

package com.demo.factory.model.kfc;
import com.demo.factory.model.Hamburg;
/**
 * 中国风味的麻辣鸡腿汉堡
 *
 * @author maofw
 *
 */
public class ChinaHanburm extends Hamburg
{
  /**
   * 构造方法
   *
   * @param kind
   * @param price
   * @param num
   */
  public ChinaHanburm(int num)
  {
    this.kind = "麻辣";
    this.price = 14.0f;
    this.num = num;
  }
}

奥尔良鸡翅——ChinaChickenWings

package com.demo.factory.model.kfc;
import com.demo.factory.model.ChickenWings;
/**
 * 鸡翅实现类
 *
 * @author maofw
 *
 */
public class ChinaChickenWings extends ChickenWings
{
  public ChinaChickenWings(int num)
  {
    this.kind = "奥尔良";
    this.price = 2.5f;
    this.num = num;
  }
}

薯条——ChinaFrenchFries

package com.demo.factory.model.kfc;
import com.demo.factory.model.FrenchFries;
/**
 * 薯条实现类
 *
 * @author maofw
 *
 */
public class ChinaFrenchFries extends FrenchFries
{
  public ChinaFrenchFries(int num)
  {
    this.kind = "普通";
    this.price = 8.0f;
    this.num = num;
  }
}

可乐——ChinaBeverage

package com.demo.factory.model.kfc;
import com.demo.factory.model.Beverage;
/**
 * 饮料实现类
 *
 * @author maofw
 *
 */
public class ChinaBeverage extends Beverage
{
  public ChinaBeverage(int num)
  {
    this.kind = "可乐";
    this.price = 7.0f;
    this.num = num;
  }
}

3.4 建立工厂

创建抽象肯德基工厂——IKfcFactory 生产抽象食物

package com.demo.factory.itf;
import com.demo.factory.model.Beverage;
import com.demo.factory.model.ChickenWings;
import com.demo.factory.model.FrenchFries;
import com.demo.factory.model.Hamburg;
/**
 * 肯德基抽象工厂基类
 *
 * @author maofw
 *
 */
public interface IKfcFactory
{
  // 生产汉堡
  public Hamburg createHamburg(int num);
  // 生产薯条
  public FrenchFries createFrenchFries(int num);
  // 生产鸡翅
  public ChickenWings createChickenWings(int num);
  // 生产饮料
  public Beverage createBeverage(int num);
}

创建具体肯德基工厂——ChinaKfcFactory 生产具体食物

package com.demo.factory.itf;
import com.demo.factory.model.Beverage;
import com.demo.factory.model.ChickenWings;
import com.demo.factory.model.FrenchFries;
import com.demo.factory.model.Hamburg;
import com.demo.factory.model.kfc.ChinaBeverage;
import com.demo.factory.model.kfc.ChinaChickenWings;
import com.demo.factory.model.kfc.ChinaFrenchFries;
import com.demo.factory.model.kfc.ChinaHanburm;
public class ChinaKfcFactory implements IKfcFactory
{
  // 生产可乐
  public Beverage createBeverage(int num)
  {
    return new ChinaBeverage(num);
  }
  // 生产奥尔良烤鸡翅
  public ChickenWings createChickenWings(int num)
  {
    return new ChinaChickenWings(num);
  }
  // 生产薯条
  public FrenchFries createFrenchFries(int num)
  {
    return new ChinaFrenchFries(num);
  }
  // 生产麻辣风味鸡腿汉堡
  public Hamburg createHamburg(int num)
  {
    return new ChinaHanburm(num);
  }
}

3.5 创建客户类——Customer

package com.demo.factory.custom;
import com.demo.factory.itf.IKfcFactory;
import com.demo.factory.model.Beverage;
import com.demo.factory.model.ChickenWings;
import com.demo.factory.model.FrenchFries;
import com.demo.factory.model.Hamburg;
/**
 * 客户类
 *
 * @author maofw
 *
 */
public class Customer
{
  // 抽象工厂
  private IKfcFactory kfcFactory;
  // 构造方法将抽象工厂作为参数传入
  public Customer(IKfcFactory kfcFactory)
  {
    this.kfcFactory = kfcFactory;
  }
  /**
   * 订购食物
   */
  // 订购麻辣鸡腿汉堡
  public float orderHamburg(int num)
  {
    // 获得麻辣鸡腿汉堡
    Hamburg hamburg = kfcFactory.createHamburg(num);
    // 输出订购信息
    hamburg.printMesage();
    // 返回总价
    return hamburg.totalPrice();
  }
  // 订购奥尔良烤鸡翅
  public float orderChickenWings(int num)
  {
    // 获得奥尔良烤鸡翅
    ChickenWings chickenWings = kfcFactory.createChickenWings(num);
    // 输出订购信息
    chickenWings.printMesage();
    // 返回总价
    return chickenWings.totalPrice();
  }
  // 订购薯条
  public float orderFrenchFries(int num)
  {
    // 获得薯条
    FrenchFries frenchFries = kfcFactory.createFrenchFries(num);
    // 输出订购信息
    frenchFries.printMesage();
    // 返回总价
    return frenchFries.totalPrice();
  }
  // 订购可乐
  public float orderBeverage(int num)
  {
    // 获得可乐
    Beverage beverage = kfcFactory.createBeverage(num);
    // 输出订购信息
    beverage.printMesage();
    // 返回总价
    return beverage.totalPrice();
  }
}

3.6 故事情节展现

package com.demo.factory;
import java.lang.management.ManagementFactory;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.ResourceBundle;
import com.demo.factory.custom.Customer;
import com.demo.factory.itf.ChinaKfcFactory;
import com.demo.factory.itf.IKfcFactory;
public class MainApp
{
  /**
   * 主应用程序方法
   *
   * @param args
   */
  public static void main(String[] args)
  {
    /**
     * 定义一个肯德基(IKfcFactory类型)
     */
    IKfcFactory kfcFactory = new ChinaKfcFactory();
    /**
     * 爸爸和儿子走进肯德基,准备点餐
     */
    Customer customer = new Customer(kfcFactory);
    /**
     * 开始点餐
     */
    // 一个麻辣鸡腿汉堡
    float hamhurgMoney = customer.orderHamburg(1);
    // 四个奥尔良烤鸡翅
    float chickenWingsMoney = customer.orderChickenWings(4);
    // 一包薯条
    float frenchFriesMoney = customer.orderFrenchFries(1);
    // 两杯可乐
    float beverageMoney = customer.orderBeverage(2);
    System.out.println("总计:" + (hamhurgMoney + chickenWingsMoney + frenchFriesMoney + beverageMoney));
  }
}

运行结果:

--麻辣风味汉堡, 单价:14.0, 数量:1, 合计:14.0
--奥尔良风味鸡翅, 单价:2.5, 数量:4, 合计:10.0
--普通风味薯条, 单价:8.0, 数量:1, 合计:8.0
--可乐饮料, 单价:7.0, 数量:2, 合计:14.0
总计:46.0

三、该模式的设计原则

1 多用对象组合,少用继承
2 针对抽象编程,不针对实现编程
3 产品对象通过工厂暴露的方法创建

四、使用场合

1 创建产品家族,相关产品集合在一起使用的时候;
2 想要提供一个产品类库,并只想显示其接口而不是实现时;
3 通过组合的方式使用工厂时。

更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。

时间: 2018-05-16

Java设计模式之工厂模式分析【简单工厂、工厂方法、抽象工厂】

本文实例讲述了Java设计模式之工厂模式.分享给大家供大家参考,具体如下: 一. 简单工厂 先来思考一个问题.我们平时写程序时,会有这种情况,A对象里面需要调用B对象的方法,这时我们使用的一般是new关键字来创建一个B实例,然后调用B实例的方法.这种做法的坏处在于:A类的方法实现直接调用了B类的类名(这种方式也被称为硬编码耦合),一旦系统需要重构:需要使用C类来代替B类时,程序就不得不修改A类代码,如果应用中有100个或者10000个类以硬编码方式耦合了B类,则需要修改100个.10000个地方

JDK8接口的默认与静态方法-接口与抽象类的区别详解

引入 JDK1.8后,接口允许定义默认方法与静态方法,如:Iterable类中的foreach方法. public interface Iterable<T> { /** * Returns an iterator over elements of type {@code T}. * * @return an Iterator. */ Iterator<T> iterator(); /** * Performs the given action for each element o

详解Java中AbstractMap抽象类

jdk1.8.0_144 下载地址:http://www.jb51.net/softs/551512.html AbstractMap抽象类实现了一些简单且通用的方法,本身并不难.但在这个抽象类中有两个方法非常值得关注,keySet和values方法源码的实现可以说是教科书式的典范. 抽象类通常作为一种骨架实现,为各自子类实现公共的方法.上一篇我们讲解了Map接口,此篇对AbstractMap抽象类进行剖析研究. Java中Map类型的数据结构有相当多,AbstractMap作为它们的骨架实现实

Java设计模式之抽象工厂模式

一.场景描述 接<Java设计模式(一)工厂模式> 工厂模式有一缺点,就是破坏了类的封闭性原则.例如,如果需要增加Word文件的数据采集,此时按以下步骤操作: 创建Word文件数据采集类,实现仪器数据采集接口: 修改仪器数据采集工厂类,增加Word文件数据采集类的工厂方法: 调用工厂类的word文件方法: 步骤2修改了工厂类,如果每增加一实现类都需要修改工厂类,那么这样就不合理了. 解决办法是使用抽象工厂类,为每一个实现类都创建其工厂类,并增加工厂接口,使各工厂类实现该接口. 使用抽象工厂后,

Java抽象类的概念讲解

简单来说 抽象类通常用来作为一个类族的最顶端的父类,用最底层的类表示现实中的具体事物,用最顶层的类表示该类族所有事物的共性.用abstract关键字类修饰一个类,该类叫做抽象类. 有抽象类那么肯定也有抽象方法,什么是抽象方法呢? 抽象方法就是有名字,形参列表,返回值,没有方法体的方法就做抽象方法. 抽象方法和抽象类的关系? 凡是没有方法体的方法必须使用关键字abstract修饰为抽象方法. 凡是含有抽象方法的类必须声明为抽象类. abstract class A{ abstract public

细数Java接口的概念、分类及与抽象类的区别

Java接口(Interface),是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能). 一.接口含义: 1.Java接口,Java语言中存在的结构,有特定的语法和结构: 2.一个类所具有的方法的特征集合,是一种逻辑上的抽象. 前者叫做"Java接口",后者叫做"接口". Java接口本身没有任何实现,因为Java接口不涉及表象,而只描述public行为,所

Java抽象类概念与用法实例分析

本文实例讲述了Java抽象类概念与用法.分享给大家供大家参考,具体如下: 抽象:就是对一个事物的大概描述 抽象方法:以abstract修饰的方法,这种方法只声明返回数据类型,方法名和所需参数,并没有函数体.如 abstract void study(); 抽象类特点: 1.抽象类中不一定含有抽象方法:但抽象方法一定在抽象类中. 2.抽象类不具备实际功能,只能用于派生子类 3.抽象类中可以包含构造函数,但是构造函数不能被声明成抽象.抽象类中的成员方法包括一般方法和抽象方法 4.抽象方法和抽象类都必

Java 抽象类与接口的对比

其实说实话,没有多大的可比较性,它们是完全不同的两个东西,它们的抽象不在同一个层级上.但是为了让大家更好的理解,还是做一个比较吧,毕竟它们都很抽象(233). 首先是语法层面上的对比 1)抽象类跟接口都不能被实例化,因为它们都很虚嘛.但是在访问权限上,两者有一定的区别. a.抽象类中的抽象方法(其前有abstract修饰)不能用private.static.synchronized.native访问修饰符修饰.理由很简单,容我慢慢道来. 抽象方法是没有方法体的,它的目的就是用来继承的,所以如果使

java 抽象类的实例详解

java 抽象类的实例详解 前言: 什么是抽象类?这名字听着就挺抽象的,第一次听到这个名字还真有可能被唬住.但是,就像老人家所说的,一切反动派都是纸老虎,一切有着装x名字的概念也是纸老虎.好吧,我们已经从战略上做到了藐视它,现在就要战术上重视它,如同要解决纸老虎,就要一个牙齿一个牙齿地敲,一个爪子一个爪子地拔:解决这种抽象概念也一样,先要把它具体化,细分化,然后一个一个地来. 我一般遇到新的概念都会问三个问题: 1.这个东西有什么用?用来干什么的?它的意义在哪里?(显然,如果是没用的东西,就没必

java 抽象类与接口的区别总结

java 抽象类与接口的区别总结 abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力. abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于 abstract class和interface 选择显得比较随意. 其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对于问题领域本质的 理解

深入浅出分析Java抽象类和接口【功能,定义,用法,区别】

本文实例讲述了Java抽象类和接口.分享给大家供大家参考,具体如下: 对于OOP编程来说,抽象是它一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:抽象类和接口. 这两者有相似之处也有很大的不同之处. 一.抽象类 在了解抽象类之前,先了解下抽象方法.抽象方法是一种特殊的方法:只有声明,而没有具体的实现.抽象方法的声明格式为: abstract void fun(); 抽象方法必须用abstract关键字进行修饰.如果一个类含有抽象方法,则称这个类为抽象类,这个类就必须在类前用abs

Java抽象类和抽象方法定义与用法实例详解

本文实例讲述了Java抽象类和抽象方法定义与用法.分享给大家供大家参考,具体如下: 一.Java抽象类 参考资料:Java抽象类 详解 1.抽象类的说明 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量.成员方法和构造方法的访问方式和普通类一样. 由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用.也是因为这

Java抽象类原理与用法实例详解

本文实例讲述了Java抽象类原理与用法.分享给大家供大家参考,具体如下: 一.抽象类的基本概念 普通类是一个完善的功能类,可以直接产生实例化对象,并且在普通类中可以包含有构造方法.普通方法.static方法.常量和变量等内容.而抽象类是指在普通类的结构里面增加抽象方法的组成部分. 那么什么叫抽象方法呢?在所有的普通方法上面都会有一个"{}",这个表示方法体,有方法体的方法一定可以被对象直接使用.而抽象方法,是指没有方法体的方法,同时抽象方法还必须使用关键字abstract做修饰. 而拥

Java钩子方法概念原理详解

这篇文章主要介绍了Java钩子方法概念原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 钩子方法源于设计模式中模板方法(Template Method)模式,模板方法模式的概念为:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤.其主要分为两大类:模版方法和基本方法,而基本方法又分为:抽象方法(Abstract Method),具体方法(Concrete Me