工厂模式
- 概述
- 常见分类
- 简单工厂模式
- 概述
- 设计
- 图解
- 创建People抽象类(产品说明书)
- 创建子类(产品角色)
- 创建工厂(用于根据需求实例化对象)
- 消费者
- 简单工厂模式优点
- 简单工厂模式缺点
- 工厂方法模式
- 概述
- 设计
- 图解
- 创建抽象父类(产品说明书)
- 子类(产品角色)
- 工厂
- 工厂接口实现类(车间)
- 消费者
- 优点
- 缺点
概述
我们一般通过new创建对象,创建对象时根据需求通过构造函数对对象的属性值进行初始
化。
第一:如果需求过多,会在构造函数中进行大量初始化的操作,导致代码过多可读性降低。
第二:假如需要创建大量属性name='张三’的Student对象时,每次创建都会去设置属性值。
按照实际生活中来说,如果某种东西需求达到一定程度时,就要施行量产,就需要工厂来实现此操作
常见分类
简单工厂模式
概述
People zhangsan = new People("张三",18,'男');
People zhangsan2 = new People("张三",18,'男');
People zhangsan3 = new People("张三",18,'男');
当大量需要创建"张三"这个对象时,就需要一个工厂来代替我们去生产张三这
个对象
设计:
1.将People声明为抽象类
2.创建张三这个类继承该类,通过父类构造器初始化属性值
3.同样地,要实例化一个李四对象,就创建李四这个类继承People类
在现实生活中,工厂生产东西需要说明书,以及根据说明书设计出来的产
品称之为产品角色,再交给工厂生产,最后满足消费者的需求。 在Java的
工厂设计模式中,可以理解为以下这样关系。
设计
说明书------>抽象父类
产品角色---->抽象父类子类
工厂------>用于创建子类对象的类
图解
创建People抽象类(产品说明书)
public abstract class People {
private String name;
private int age;
private char sex;
private People() {
}
public People(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
创建子类(产品角色)
public class Lisi extends People {
public Lisi(){
super("李四",20,'女');
}
}
public class ZhangSan extends People {
//初始化属性
public ZhangSan(){
super("张三",18,'男');
}
}
创建工厂(用于根据需求实例化对象)
public class PeopleFactory {
//造产品
public People createPeople(String order){
switch (order){
case "zs":
return new ZhangSan();
case "lisi":
return new Lisi();
default:
System.out.println("没有该产品!");
return null;
}
}
}
消费者
public class Consumer {
public static void main(String[] args) {
//创建工厂对象
PeopleFactory p = new PeopleFactory();
//需要张三
People zhangsan = p.createPeople("zs");
System.out.println(zhangsan);
//需要李四
People lisi = p.createPeople("lisi");
System.out.println(lisi);
}
}
简单工厂模式优点
简单工厂模式提供专门的工厂类用于创建对象,实现了对象创建和使用的
职责分离, 客户端不需知道所创建的具体产品类的类名以及创建过程,只
需知道具体产品类所对应的参数即可。
简单工厂模式缺点
需要其它对象时比如 王五,赵六…等对象,也要重复执行上述操作,会大
量创建类,同样地每次添加新产品就需要修改工厂类。在产品类型较多
时,有可能造成工厂逻辑过于复杂,不利于系统的扩展维护。
我们不仅开放了扩展,还开放了修改,这样就违反了 开放 - 封闭 原则。
工厂方法模式
概述
工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加
新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定
要实例化的产品是哪个,在子类中将对象进行创建,这样工厂的设计就符
合“开闭原则”了,扩展时不必去修改原来的代码。
设计
产品说明书(抽象父类)
产品角色(子类)
工厂(工厂接口)
车间(工厂接口实现类—创建对象)
客户
图解
工厂方法模式相对于在简单工厂模式来说,将工厂进行了改造:简单工厂模
式相当于将所有的产品放在一条流水线上生产,而工厂方法模式设置了产
品车间(每个工厂实现类),每个车间生产不同产品相当于多条流水线各自生
产不同的产品。当我们要增加一个产品时,只需加一个车间即可(创建一个
工厂实现类),不会改变整个工厂的结构。
创建抽象父类(产品说明书)
abstract public class Phone {
private String type;
private int ram;
private String handler;
public Phone() {
}
public Phone(String type, int ram, String handler) {
this.type =type;
this.ram = ram;
this.handler = handler;
}
@Override
public String toString() {
return "Phone{" +
"type='" + type + '\'' +
", ram=" + ram +
", handler='" + handler + '\'' +
'}';
}
}
子类(产品角色)
public class Apple extends Phone {
public Apple(){
super("苹果50Pro Max",64,"A100");
}
}
public class HUAWEI extends Phone {
public HUAWEI(){
super("p100",128,"天玑200000");
}
}
工厂
//工厂
public interface PhoneFactory {
//产品线---造手机
Phone createPhone();
}
工厂接口实现类(车间)
//造苹果的车间
public class AppleFactory implements PhoneFactory {
@Override
public Phone createPhone() {
return new Apple();
}
}
//造华为的车间
public class HUAWEIFactory implements PhoneFactory {
@Override
public Phone createPhone() {
return new HUAWEI();
}
}
消费者
public class Consumer {
public static void main(String[] args) {
//创建华为工厂对象
HUAWEIFactory huawei = new HUAWEIFactory();
//创建苹果工厂对象
AppleFactory apple = new AppleFactory();
//造华为
Phone p1 = huawei.createPhone();
System.out.println(p1);
//造苹果
Phone p2 = apple.createPhone();
System.out.println(p2);
}
}
优点
更符合开-闭原则,新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可。
符合单一职责原则,每个具体工厂类只负责创建对应的产品。
工厂模式是简单工厂模式的进一步抽象和拓展,保留了简单工厂的封装优点同时,让扩展变得简单,让继承变得可行。
使用这种设计方式后,当新创建一个抽象父类的子类时,只需再创建一个实现工厂接口的实现类用于创建子类对象即可。
缺点
一个工厂只能创建一种对应的具体产品。
添加新产品时,除了增加新产品类外,还要具体工厂类,系统类的个数将成对增加,增加了系统的复杂度。
由于考虑到系统的可扩展性,需要引入抽象层,增加了系统的抽象性和理解难度。
要更换另外一种产品,仍然需要修改实例化的具体工厂类。