一、简单工厂模式
1、传统方式实现披萨订购( 可以忽略)
披萨父类 Pizza
package tanchishell.SJMS.factory;
//抽象类 Pizza 后续的所有 披萨都继承该类
public abstract class Pizza {
protected String name;
//由于不同的披萨有着不同的原材料所有 准备原材料的方法是抽象的需要子类自己去实现
public abstract void prepare();
//一下流程是各种披萨共有的,子类继承后自动实现
public void bake() {
System.out.println(name + " baking;");
}
public void cut() {
System.out.println(name + " cutting;");
}
public void box() {
System.out.println(name + " boxing;");
}
public void setName(String name) {
this.name = name;
}
}
子类胡椒披萨 PepperPizza
package tanchishell.SJMS.factory;
public class PepperPizza extends Pizza{
@Override
public void prepare() {
System.out.println("准备胡椒披萨的原材料");
}
}
子类印度披萨 GreekPizza
package tanchishell.SJMS.factory;
public class GreekPizza extends Pizza{
@Override
public void prepare() {
System.out.println("准备希腊披萨的原材料");
}
}
订购披萨 OrderPizza
package tanchishell.SJMS.factory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class OrderPizza {
//构造器
public OrderPizza() {
Pizza pizza = null;
String orderType; // 订购披萨的类型
do {
orderType = getType();
if (orderType.equals("greek")) {
pizza = new GreekPizza();
pizza.setName(" 希腊披萨 ");
} else if (orderType.equals("pepper")) {
pizza = new PepperPizza();
pizza.setName("胡椒披萨");
} else {
System.out.println("请检查您的输入");
break;
}
//输出 pizza 制作过程
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} while (true);
}
//获取披萨的类型
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza 类型:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
订购披萨的 客户端 PizzaStore
package tanchishell.SJMS.factory;
//订购Pizza的客户端
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza();
}
}
运行结果
传统的方式的优缺点,新增子类需要修改的地方牵扯太多
传统方式的究极耦合
新增一个子类,所有的OrderPizza类都需要修改,一旦过多,耦合度极高。
2、使用简单工厂模式 🔞🔞🔞
完整代码
披萨父类 Pizza
package tanchishell.SJMS.factory;
//抽象类 Pizza 后续的所有 披萨都继承该类
public abstract class Pizza {
protected String name;
//由于不同的披萨有着不同的原材料所有 准备原材料的方法是抽象的需要子类自己去实现
public abstract void prepare();
//以下流程是各种披萨共有的,子类继承后自动实现
public void bake() {
System.out.println(name + " baking;");
}
public void cut() {
System.out.println(name + " cutting;");
}
public void box() {
System.out.println(name + " boxing;");
}
public void setName(String name) {
this.name = name;
}
}
披萨子类 GreekPizza / PepperPizza / ChinesePizza
印度披萨
package tanchishell.SJMS.factory;
public class GreekPizza extends Pizza{
@Override
public void prepare() {
System.out.println("准备希腊披萨的原材料");
}
}
胡椒披萨
package tanchishell.SJMS.factory;
public class PepperPizza extends Pizza{
@Override
public void prepare() {
System.out.println("准备胡椒披萨的原材料");
}
}
中国披萨
package tanchishell.SJMS.factory;
public class ChinesePizza extends Pizza {
@Override
public void prepare() {
System.out.println("准备中国披萨的原材料");
}
}
订购披萨 OrderPizza
package tanchishell.SJMS.factory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class OrderPizza{
//定义一个简单工厂对象
// SimpleFactory simpleFactory = new SimpleFactory(); //如果OrderPizza 和 工厂类同生共死就是组合关系
SimpleFactory simpleFactory;
Pizza pizza = null;
//构造器
public OrderPizza(SimpleFactory simpleFactory) {
setFactory(simpleFactory);
}
public void setFactory(SimpleFactory simpleFactory) {
String orderType = ""; //用户输入的,先定义一个空串提供下面使用
this.simpleFactory = simpleFactory; //设置简单工厂对象
do {
orderType = getType();
//可以在这里更换工厂方法
pizza = this.simpleFactory.createPizza(orderType);
//输出 pizza
if(pizza != null) { //订购成功
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} else {
System.out.println(" 订购披萨失败 ");
break;
}
}while(true);
}
//获取用户需要披萨的类型
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza 类型:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
披萨简单工厂 SimpleFactory
package tanchishell.SJMS.factory;
/**
* 添加新品种的 披萨 只需要添加一个Pizza子类和在工厂类中做一个判断
*/
public class SimpleFactory {
//更加 orderType 返回对应的 Pizza 对象
public Pizza createPizza(String orderType) {
Pizza pizza = null;
System.out.println("使用简单工厂模式");
if (orderType.equals("greek")) {
pizza = new GreekPizza();
pizza.setName(" 希腊披萨 ");
} else if (orderType.equals("chinese")) {
pizza = new ChinesePizza();
pizza.setName(" 中国披萨 ");
} else if (orderType.equals("pepper")) {
pizza = new PepperPizza();
pizza.setName("胡椒披萨");
}else if (orderType.equals("usa")){ //新增美国披萨
pizza = new USAPizza();
pizza.setName("我是美国披萨");
}
return pizza;
}
//简单工厂模式 也叫 静态工厂模
public static Pizza createPizza2(String orderType) {
Pizza pizza = null;
System.out.println("使用简单工厂模式 2");
if (orderType.equals("greek")) {
pizza = new GreekPizza();
pizza.setName(" 希腊披萨 ");
} else if (orderType.equals("chinese")) {
pizza = new ChinesePizza();
pizza.setName(" 中国披萨 ");
} else if (orderType.equals("pepper")) {
pizza = new PepperPizza();
pizza.setName("胡椒披萨");
}
return pizza;
}
}
客户端订购披萨 PizzaStore
package tanchishell.SJMS.factory;
//订购Pizza的客户端
public class PizzaStore {
public static void main(String[] args) {
// new OrderPizza();
//获取订单,传入一个工厂
new OrderPizza(new SimpleFactory());
System.out.println("退出程序");
}
}
添加披萨子类 USAPizza 美国披萨
package tanchishell.SJMS.factory;
public class USAPizza extends Pizza{
@Override
public void prepare() {
System.out.println("准备制作美国披萨");
}
}
运行结果
二、工厂方法模式
完整代码
披萨父类 Pizza
package tanchishell.SJMS.methedfactory;
//抽象类 Pizza 后续的所有 披萨都继承该类
public abstract class Pizza {
protected String name;
//由于不同的披萨有着不同的原材料所有 准备原材料的方法是抽象的需要子类自己去实现
public abstract void prepare();
//以下流程是各种披萨共有的,子类继承后自动实现
public void bake() {
System.out.println(name + " baking;");
}
public void cut() {
System.out.println(name + " cutting;");
}
public void box() {
System.out.println(name + " boxing;");
}
public void setName(String name) {
this.name = name;
}
}
北京奶酪披萨 BJCheesePizza
public class BJCheesePizza extends Pizza{
@Override
public void prepare() {
setName("北京奶酪披萨");
System.out.println("准备北京制作奶酪披萨");
}
}
北京胡椒披萨 BJPepperPizza
public class BJPepperPizza extends Pizza {
@Override
public void prepare() {
setName("北京胡椒披萨");
System.out.println("准备北京胡椒披萨的原材料");
}
}
伦敦奶酪披萨 LDCheesePizza
public class LDCheesePizza extends Pizza{
@Override
public void prepare() {
setName("伦敦奶酪披萨");
System.out.println("准备伦敦制作奶酪披萨");
}
}
伦敦胡椒披萨 LDPepperPizza
public class LDPepperPizza extends Pizza {
@Override
public void prepare() {
setName("伦敦胡椒披萨");
System.out.println("准备伦敦胡椒披萨的原材料");
}
}
抽象订购披萨 OrderPizza (充当工厂角色)
package tanchishell.SJMS.methedfactory;
import tanchishell.SJMS.factory.SimpleFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public abstract class OrderPizza {
//定义一个抽象方法,createPizza , 让各个工厂子类自己实现
abstract Pizza createPizza(String orderType);
// 构造器
public OrderPizza() {
Pizza pizza = null;
String orderType; // 订购披萨的类型
do {
orderType = getType();
pizza = createPizza(orderType); //抽象方法,由工厂子类完成
//输出 pizza 制作过程
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} while (true);
}
//获取用户需要披萨的类型
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza 类型: ---- pepper(胡椒口味) -----cheese(奶酪口味)");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
订购披萨子类 BJOrderPizza / LDOrderPizza
BJOrderPizza
package tanchishell.SJMS.methedfactory;
public class BJOrderPizza extends OrderPizza{
@Override
Pizza createPizza(String orderType) {
Pizza pizza = null;
if(orderType.equals("cheese")) {
pizza = new BJCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new BJPepperPizza();
}
/**
* 需要添加北京口味的披萨只需要设计一个披萨子类 并在 这里加一个判断
*/
return pizza;
}
}
LDOrderPizza
package tanchishell.SJMS.methedfactory;
public class LDOrderPizza extends OrderPizza{
@Override
Pizza createPizza(String orderType) {
Pizza pizza = null;
if(orderType.equals("cheese")) {
pizza = new LDCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new LDPepperPizza();
}
// TODO Auto-generated method stub
return pizza;
}
}
客户端订购披萨
package tanchishell.SJMS.methedfactory;
import java.util.Scanner;
public class PizzaStore {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请选择您的口味---目前支持 1,北京口味 ----2,伦敦口味");
int i = scanner.nextInt();
if(i == 1){
new BJOrderPizza();
}
if(i == 2){
new LDOrderPizza();
}
}
}
运行结果
添加披萨口味
新增子类实现
在对应的 Order 实现类进行判断
测试
三、抽象工厂模式
抽象工厂模式是对简单工厂和工厂方法的一个整合
代码示例
pizza 代码和 工厂方法模式一致,就不写了
抽象工厂 AbsFactory 接口
public interface AbsFactory {
//让下面的工厂子类来 具体实现
Pizza createPizza(String orderType);
}
北京披萨工厂 BJFactory 实现 AbsFactory 接口
package tanchishell.SJMS.absFactory;
public class BJFactory implements AbsFactory{
@Override
public Pizza createPizza(String orderType) {
System.out.println("~使用的是抽象工厂模式~");
Pizza pizza = null;
if(orderType.equals("cheese")) {
pizza = new BJCheesePizza();
} else if (orderType.equals("pepper")){
pizza = new BJPepperPizza();
}
/**
* 添加披萨子类和判断就能完成披萨口味的添加
*/
return pizza;
}
}
伦敦披萨工厂 LDFactory 实现 AbsFactory 接口
package tanchishell.SJMS.absFactory;
public class LDFactory implements AbsFactory{
@Override
public Pizza createPizza(String orderType) {
System.out.println("~使用的是抽象工厂模式~");
Pizza pizza = null;
if (orderType.equals("cheese")) {
pizza = new LDCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new LDPepperPizza();
}
return pizza;
}
}
披萨订购 OrderPizza 聚合 AbsFactory 接口
package tanchishell.SJMS.absFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class OrderPizza {
AbsFactory factory;
// 构造器
public OrderPizza(AbsFactory factory) {
setFactory(factory);
}
private void setFactory(AbsFactory factory) {
Pizza pizza = null;
String orderType = ""; // 用户输入
this.factory = factory;
do {
orderType = getType();
// factory 可能是北京的工厂子类,也可能是伦敦的工厂子类
pizza = factory.createPizza(orderType);
if (pizza != null) { // 订购 ok
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} else {
System.out.println("订购失败");
break;
}
} while (true);
}
// 写一个方法,可以获取客户希望订购的披萨种类
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza 类型: ---- pepper(胡椒口味) -----cheese(奶酪口味)");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
客户端订购披萨
package tanchishell.SJMS.absFactory;
import java.util.Scanner;
public class PizzaStore {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请选择您的口味---目前支持 1,北京口味 ----2,伦敦口味");
int i = scanner.nextInt();
if(i == 1){
new OrderPizza(new BJFactory());
}
if(i == 2){
new OrderPizza(new LDFactory());
}
}
}
运行结果
JDKの工厂模式: Calendar日历类
Calendar cal = Calendar.getInstance();
// 注意月份下标从0开始,所以取月份要+1
System.out.println("年:" + cal.get(Calendar.YEAR));
System.out.println("月:" + (cal.get(Calendar.MONTH) + 1));
System.out.println("日:" + cal.get(Calendar.DAY_OF_MONTH));
System.out.println("时:" + cal.get(Calendar.HOUR_OF_DAY));
System.out.println("分:" + cal.get(Calendar.MINUTE));
System.out.println("秒:" + cal.get(Calendar.SECOND));
进入Calendar cal = Calendar.getInstance();