一,什么是工厂模式?为什么使用工厂模式?
将对象的实例化全部交给工厂去做,你只需要告诉工厂需要什么对象,然后工厂造出来就行。让使用者只需要关注自己的需求,不需要关注这个东西如何创建,能用就行。
二,三种实现方式
需求案例:
披萨制作:便于披萨种类的扩展,要便于维护: 披萨种类很多:GreekPizz,chesePizz等
1.简单工厂
生产披萨
在简单工厂模式中创建实例的方法通常为静态(static)方法,因此简单工厂模式(Simple Factory Pattern)又叫作静态工厂方法模式(Static Factory Method Pattern)。
主要角色如下: 简单工厂(SimpleFactory):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。 抽象产品(Product):是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。 具体产品(ConcreteProduct):是简单工厂模式的创建目标。
抽象产品
代码语言:javascript复制//pizza抽象类:
public abstract class Pizza {
public abstract void name();
}
具体产品
代码语言:javascript复制//GreekPizz类
public class GreekPizza extends Pizza {
@Override
public void name() {
System.out.println("希腊披萨");
}
}
代码语言:javascript复制//CheessPizza类
public class CheessPizza extends Pizza {
@Override
public void name() {
System.out.println("奶酪披萨");
}
}
简单工厂
代码语言:javascript复制public abstract class SimpleFactory {
//创建披萨的方法
public static Pizza getPizza(String name){
if("greek".equals(name)){
return new GreekPizza();
} else if ("cheess".equals(name)) {
return new CheessPizza();
}
else{
return null;
}
}
}
测试类:
代码语言:javascript复制public class SimpleFactoryTest {
public static void main(String[] args) {
//直接调用工厂类创建披萨的方法,不需要知道具体的细节,只需要知道披萨名
Pizza pizza1 = SimpleFactory.getPizza("greek");
Pizza pizza2 = SimpleFactory.getPizza("cheess");
pizza1.name();//希腊披萨
pizza2.name();//奶酪披萨
}
}
分析: 如果再加一个种类的pizza,例如胡椒(pepper)pizza,那么还得修改工厂类,简单工厂模式每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度,违背了“开闭原则”。
2.工厂方法
生产多种类披萨
“工厂方法模式”是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。
主要角色如下。 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
抽象产品
代码语言:javascript复制public abstract class Pizza {
public abstract void name();
}
具体产品
希腊披萨
代码语言:javascript复制public class GreekPizza extends Pizza {
@Override
public void name() {
System.out.println("希腊披萨");
}
}
奶酪披萨
代码语言:javascript复制public class CheessPizza extends Pizza {
@Override
public void name() {
System.out.println("奶酪披萨");
}
}
抽象工厂
代码语言:javascript复制public abstract class FactoryMethod {
//创建产品的方法
public abstract Pizza createPizza();
}
具体工厂
生产奶酪披萨的工厂
代码语言:javascript复制public class FactoryMethodCheess extends FactoryMethod{
@Override
public Pizza createPizza() {
return new CheessPizza();
}
}
生产希腊披萨的工厂
代码语言:javascript复制public class FactoryMethodGreek extends FactoryMethod{
@Override
public Pizza createPizza() {
return new GreekPizza();
}
}
测试类
代码语言:javascript复制public class FactoryMethodTest {
public static void main(String[] args) {
//调用具体工厂,由具体工厂实现
Pizza pizza = new FactoryMethodCheess().createPizza();
Pizza pizza1 = new FactoryMethodGreek().createPizza();
pizza.name();
pizza1.name();
}
}
3.抽象工厂
抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
主要角色如下 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
抽象产品
手机产品接口
代码语言:javascript复制public interface IPhoneProduct {
void start();
void shutdown();
}
笔记本产品接口
代码语言:javascript复制public interface noteBookProduct {
void start();
void shutdown();
}
抽象工厂
手机是一个产品等级,笔记本又是一个产品等级
代码语言:javascript复制public interface IProductFactory {
//生产手机
IPhoneProduct iPhoneProduct();
//生产笔记本
NoteBookProduct noteBookProduct();
}
具体工厂
小米工厂,这是一个产品族
代码语言:javascript复制public class MIUIProduct implements IProductFactory{
//下面是两个不同的产品等级
@Override
public IPhoneProduct iPhoneProduct() {
return new MIUIPPhone();
}
@Override
public NoteBookProduct noteBookProduct() {
return new MIUInotebook();
}
}
华为工厂,这又是一个产品族
代码语言:javascript复制public class HuaweiProduct implements IProductFactory{
//下面是两个不同的产品等级
@Override
public NoteBookProduct iPhoneProduct() {
return new HuaweiPhone();
}
@Override
public NoteBookProduct noteBookProduct() {
return new HuaweiNoteBook();
}
}
具体产品
代码语言:javascript复制public class MIUIPhone implements IPhoneProduct{
@Override
public void start() {
System.out.println("小米开机");
}
@Override
public void shutdown() {
System.out.println("小米关机");
}
}
代码语言:javascript复制public class MIUInotebook implements NoteBookProduct{
@Override
public void start() {
System.out.println("小米笔记本开机");
}
@Override
public void shutdown() {
System.out.println("小米笔记本关机");
}
}
代码语言:javascript复制public class HuaweiPhone implements IPhoneProduct{
@Override
public void start() {
System.out.println("华为开机");
}
@Override
public void shutdown() {
System.out.println("华为关机");
}
}
代码语言:javascript复制public class HuaweiNoteBook implements NetBookProduct{
@Override
public void start() {
System.out.println("华为笔记本开机");
}
@Override
public void shutdown() {
System.out.println("华为笔记本关机");
}
}
测试类
代码语言:javascript复制public class Consumer {
public static void main(String[] args) {
System.out.println("===========小米产品系列===========");
MIUIProduct MIUIProduct = new MIUIProduct();
//生产小米手机
IPhoneProduct iPhoneProduct = MIUIProduct.iPhoneProduct();
//生产小米笔记本
NoteBookProduct noteBookProduct = MIUIProduct.iRouteProduct();
iPhoneProduct.start();//小米开机
noteBookProduct.start();//小米笔记本开机
System.out.println("===========华为产品系列===========");
HuaweiProduct huaweiProduct = new HuaweiProduct();
//生产华为手机
IPhoneProduct iPhoneProduct1 = huaweiProduct.iPhoneProduct();
//生产华为笔记本
NoteBookProduct noteBookProduct1 = huaweiProduct.NoteBookProduct ();
iPhoneProduct1.start();//华为开机
noteBookProduct1.start();//华为笔记本开机
}
}