KFC点餐系统实现思路:
抽象工厂模式提供了一个接口,用于创建相关或者依赖对象的家族,而不需要指定具体实现类。抽象工厂模式允许客户使用抽象接口来创建一组相关的产品,客户类和工厂类分开,客户需要任何产品的时候,只需要向工厂请求即可,客户无须修改就可以获得新产品。
通过抽象工厂模式来实现,把所有的食物都抽象为一个类,并且每一个食物都由一个基类和一个接口派生出来,这样在新增其他食物的时候易于扩展。图1为食物之间的类图关系。使用文件来保存已有的菜品名,通过键值对的形式,如图2所示:在程序加载的时候会通过三个读文件的程序来读汉堡类、炸鸡类、饮品类的文件。读文件程序也是通过抽象工厂类实现,来读取不同的文件,载入到程序的菜单里,如图3所示。顾客类里实现了接口中的方法,即选择汉堡包、选择炸鸡、选择饮品三个方法,并且还有一个实例工厂属性,要在构造对象时来实例化这个工厂,在实现具体的选择食物的方法中调用这个工厂生某个具体产食物的方法来生产这个食物。这就实现了抽象工厂模式,用户只需要知道工厂中可以生产那些食物即可,没必了解具体怎么生产的。
该模式的设计原则:
1 多用对象组合,少用继承
2 针对抽象编程,不针对实现编程
3 产品对象通过工厂暴露的方法创建
食物类之间的类图关系:
图1
图2
图3
文件读取的实现方法
package com.kfc.menuread;
import java.util.Map;
//读文件的接口
public interface Reader{
public Map<?, ?> read();
}
package com.kfc.menuread;
import java.util.Map;
/**
* 读取汉堡包的类
* @author dengyong
*
*/
public class HamReader implements Reader{
//汉堡包的文件路径
public static final String PATH = "E:/我的程序设计/Hamburg.txt";
@Override
public Map<Integer, String> read() {
return ReadFile.readFile(PATH);
}
}
package com.kfc.menuread;
import java.util.Map;
/**
* 读取汉堡包的类
* @author dengyong
*
*/
public class DrinksReader implements Reader{
//文件的路径
public static final String PATH = "E:/我的程序设计/Drinks.txt";
@Override
public Map<Integer, String> read() {
return ReadFile.readFile(PATH);
}
}
package com.kfc.menuread;
import java.util.Map;
public class ChickenReader implements Reader{
//文件上的位置
public static final String PATH = "E:/我的程序设计/Chicken.txt";
@Override
public Map<Integer, String> read() {
return ReadFile.readFile(PATH);
}
}
package com.kfc.menuread;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* 具体读取文件的方法,静态方法,直接调用
* @author dengyong
*
*/
public class ReadFile {
public static Map<Integer, String> readFile(String path){
Map<Integer, String> hambuger = new HashMap<>();
try {
BufferedReader br = new BufferedReader(new FileReader(new File(path)));
String line = null;
while(null != (line = br.readLine())) {
String [] text = line.split(":");
int key = Integer.parseInt(text[0]);
hambuger.put(key, text[1]);
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return hambuger;
}
}
工厂类的实现类图:
代码实现:
package com.kfc.interfaces;
import com.kfc.chiken.ChickenWings;
import com.kfc.drink.Drinks;
import com.kfc.frencfries.FrenchFries;
import com.kfc.hamburger.HamburgerBase;
/**
* 抽象KFC工厂类
* @author dengyong
*
*/
public interface IKfcFactory
{
// 生产汉堡
public HamburgerBase createHamburg(int kind, int num);
// 生产薯条
public FrenchFries createFrenchFries(int kind, int num);
// 生产鸡翅
public ChickenWings createChickenWings(int kind, int num);
// 生产饮料
public Drinks createDrinks(int kind, int num);
}
package com.kfc.factory;
import com.kfc.chiken.Aoerliangjichi;
import com.kfc.chiken.ChickenWings;
import com.kfc.chiken.Huangjinjikuai;
import com.kfc.chiken.Jimihua;
import com.kfc.drink.Cock;
import com.kfc.drink.Drinks;
import com.kfc.drink.Milktea;
import com.kfc.drink.Xuebi;
import com.kfc.frencfries.BigFrenchFries;
import com.kfc.frencfries.FrenchFries;
import com.kfc.hamburger.Aoerliang;
import com.kfc.hamburger.HamburgerBase;
import com.kfc.hamburger.Jincuijitui;
import com.kfc.hamburger.Xianglajitui;
/***
* 具体的kfc工厂类
* 中国KFC
* @author dengyong
*
*/
public class ChinaKfcFactory implements IKfcFactory{
@Override
//负责生产汉堡包
public HamburgerBase createHamburg(int kind, int num) {
switch (kind) {
case 1:
return new Aoerliang(num);
case 2:
return new Xianglajitui(num);
case 3:
return new Jincuijitui(num);
default:
System.out.println("没有该类汉堡");
return null;
}
}
@Override
//负责生产薯条
public FrenchFries createFrenchFries(int kind, int num) {
switch (kind) {
case 4:
return new BigFrenchFries(num);
default:
System.out.println("没有该类薯条");
return null;
}
}
@Override
//负责生产鸡翅类
public ChickenWings createChickenWings(int kind, int num) {
switch (kind) {
case 1:
return new Aoerliangjichi(num);
case 2:
return new Jimihua(num);
case 3:
return new Huangjinjikuai(num);
default:
System.out.println("没有该类小吃");
return null;
}
}
@Override
//负责生产饮品
public Drinks createDrinks(int kind, int num) {
switch (kind) {
case 1:
return new Cock(num);
case 2:
return new Xuebi(num);
case 3:
return new Milktea(num);
default:
System.out.println("没有该类饮品");
return null;
}
}
}
使用场景:
假设开了家中国KFC,顾客来了点餐,顾客只需要点菜就行了,而不用知道背后是如何执行的。
调用就变得很简单:
运行结果:
消费凭单写入文件中: