工厂模式
需求
一个披萨的项目:哟啊便于披萨种类的扩展,便于维护
- 披萨的种类很多(比如 GreePizza CheesePizza等)
- 披萨的制作有
prepare(原料)
bake(烘烤)
cut(切割)
box(打包)
- 完成皮披萨的店的订购功能
传统方式
import java.util.Scanner;
/**
* 这种方式存在问题
* 如果新增一个类型的披萨,需要在OrderPizza类中修改代码
* 也需要新增一个新类型的Pizza类
* 这违反了OPC原则,即修改了使用方的代码(对扩展开放,对修改关闭)
*
* @author Han
* @data 2023/10/28
* @apiNode
*/
public class Test1 {
public static void main(String[] args) {
new OrderPizza();
}
}
abstract class Pizza {
private String name;
public abstract void prepare();
public void bake() {
System.out.println(name + " 烘烤 ");
}
public void cut() {
System.out.println(name + " 切割 ");
}
public void box() {
System.out.println(name + " 打包 ");
}
public void setName(String name) {
this.name = name;
}
}
class OrderPizza {
private Pizza pizza = null;
public OrderPizza() {
String type = this.getType();
if ("greePizza".equals(type)) {
pizza = new GreePizza();
pizza.setName("greePizza");
} else if ("cheesePizza".equals(type)) {
pizza = new CheesePizza();
pizza.setName("cheesePizza");
} else {
System.out.println("没有您这种披萨");
return;
}
// 如果新增了新类型的披萨,需要修改这里的if else逻辑(修改使用方)
pizza.bake();
pizza.cut();
pizza.box();
}
public String getType() {
System.out.println("请输入要买的披萨类型");
Scanner scna = new Scanner(System.in);
String type = scna.nextLine();
return type;
}
}
// greePizza类型的披萨
class GreePizza extends Pizza {
public GreePizza() {
this.prepare();
}
@Override
public void prepare() {
System.out.println("准备greePizza原料");
}
}
// cheesePizza类型的披萨
class CheesePizza extends Pizza {
public CheesePizza() {
this.prepare();
}
@Override
public void prepare() {
System.out.println("准备cheesePizza原料");
}
}
// 如果需要新增新类型的披萨,要对提供方代码进行修改
类图
优缺点
- 优点是比较好理解,简单易操作
- 缺点是违反了设计模式的ocp原则, 当我们给类增加新功能的时候,尽量不要修改代码,或者尽可能减少修改代码
- 比如我们这时候要新增加一个Pizza的种类,我们需要对提供方修改,也要对使用方修改,违反了opc原则
使用简单工厂模式优化
- 修改代码可以接收,但是如果在其他地方也有创建对象的代码,就意味着也要修改,而创建对象的代码,往往有多处
- 思路:把创建对象封装到一个类中,这要我们有新的pizza种类时,只需要修改该类就可以,其他创建对象的代码就不需要修改了–> 简单工厂模式
简单工厂模式
基本介绍
- 简单工厂模式是属于创建型模式,是工厂模式的一种,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,简单工厂模式是工厂模式家族中最简单使用的模式
- 简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)
- 在软件开发中,当我们会用到大量的创建某种类或某批对象是,就会使用到工厂模式
实例
package 工厂模式.简单工厂模式;
import java.util.Scanner;
// 造手机工厂
interface Phone {
void call();
}
/**
* 简单工厂模式,还是违反OCP原则
*
* @author Han
* @data 2023/10/29
* @apiNode
*/
public class SimpleFactory {
public static void main(String[] args) {
System.out.println("请输入手机品牌");
String s = new Scanner(System.in).nextLine();
PhoneFactory phoneFactory = new PhoneFactory();
phoneFactory.createPhone(s).call();
}
}
class MPhone implements Phone {
@Override
public void call() {
System.out.println("小米手机打电话");
}
}
class IPhone implements Phone {
@Override
public void call() {
System.out.println("苹果手机打电话");
}
}
class PhoneFactory {
public Phone createPhone(String name) {
if ("小米手机".equals(name)) {
return new MPhone();
} else if ("苹果手机".equals(name)) {
return new IPhone();
} else {
return null;
}
}
}
工厂方法模式
介绍
工厂方法模式设计方案: 将创建对象的功能抽象成抽象方法,在不同的子类中具体实现
工厂方法模式: 定义了一个创建对象的抽象方法,由子类决定要实例化的类,工厂方法模式将对象的实例化推迟到子类
- 工厂方法模式,创建一个工厂接口和创建多个工厂实现类,一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。有利于代码的维护和扩展。
实例
package 工厂模式.简单工厂模式;
import java.util.Scanner;
// 手机抽象类
interface Phone1 {
void call();
}
// 创建手机工厂
interface PhoneFactory1 {
Phone1 create();
}
/**
* @author Han
* @data 2023/10/29
* @apiNode
*/
public class MethodFactory {
public static void main(String[] args) {
new MPhoneFactory().create().call();
}
}
// 小米手机工厂,实现手机工厂抽象类
class MPhoneFactory implements PhoneFactory1 {
@Override
public Phone1 create() {
return new MPhone1();
}
}
// 苹果手机工厂,实现手机工厂抽象类
class IPhoneFactory implements PhoneFactory1 {
@Override
public Phone1 create() {
return new IPhone1();
}
}
// 小米手机 实现手机类
class MPhone1 implements Phone1 {
@Override
public void call() {
System.out.println("使用小米手机打电话");
}
}
// 苹果手机,实现手机类
class IPhone1 implements Phone1 {
@Override
public void call() {
System.out.println("使用苹果手机打电话");
}
}
抽象工厂模式
基本介绍
-
抽象工厂模式:定义了一个interface用来创建相关或有依赖关系的对象簇,而无需指明具体的类
-
抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合
-
从设计层面上看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)
-
将工厂抽象为两层,AbsFactory(抽象工厂)和 具体实现的工厂子类,我们可以根据创建对象类型使用对应的工厂子类,这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展
- 超级工厂
- 接口
- 下属工厂
- 产品
- 测试类
小结
- 工厂模式的意义
- 将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展性和维护性
- 三种设计模式(简单工厂模式,工厂方法模式,抽象工厂模式)
- 设计模式的依赖抽象原则
- 创建对象实例时,不要直接new类,而是把这个new类的动作放在一个工厂的方法中,并返回,有的书上说,变量不要直接持有具体类的引用
- 不要让类集成具体类,而是集成抽象类或者实现interface接口
- 不要覆盖基类中已经实现的方法