什么是工厂设计模式?
工厂设计模式,顾名思义,就是用来生产对象的,在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则,如果我们使用工厂来生产对象,我们就只和工厂打交道就可以了,彻底和对象解耦,如果要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的;所以说,工厂模式最大的优点就是:解耦
简单工厂模式(静态工厂模式)
- 简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式
- 简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)
- 在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式.
◆虽然某种程度上不符合设计原则,但实际使用最多!
我有一个汽车工厂,可以生产各种汽车对象
public class CarFactory {
public static Car GetCar(String car){
if(car.equals("宝马")){
return new BaoMa();
}else if(car.equals("奔驰")){
return new BenChi();
}else{
return null;
}
}
}
汽车生产接口
public interface Car {
void name();
}
具体类 宝马 实现接口
public class BaoMa implements Car {
@Override
public void name() {
System.out.println("宝马");
}
}
具体类 奔驰 实现接口
public class BenChi implements Car {
@Override
public void name() {
System.out.println("奔驰");
}
}
使用
Car car=CarFactory.GetCar("宝马");
Car car1=CarFactory.GetCar("奔驰");
car1.name();
car.name();
但是这时,我想要获得获得其他汽车对象,我就得修改汽车工厂,这就违背了设计模式的开闭原则。
开放-关闭原则表示软件实体 (类、模块、函数等等) 应该是可以被扩展的,但是不可被修改
工厂方法模式
- 介绍:
定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。 - 适用场景:
消费者不关心它所要创建对象的类(产品类)的时候。
消费者知道它所要创建对象的类(产品类),但不关心如何创建的时候。
◆不修改已有类的前提下,通过增加新的工厂类实现扩展,
工厂接口:
public interface CarFactory {
Car getCar();
}
宝马工厂
public class BaoMaFactory implements CarFactory {
@Override
public Car getCar() {
return new BaoMa();
}
}
奔驰工厂
public class BenChiFactory implements CarFactory {
@Override
public Car getCar() {
return new BenChi();
}
}
使用:
Car car=new BaoMaFactory().getCar();
Car car1=new BenChiFactory().getCar();
car1.name(); //奔驰
car.name(); //宝马
抽象工厂模式
- 介绍:
- 抽象工厂模式:定义了一个 interface 用于创建相关或有依赖关系的对象簇,而无需指明具体的类
- 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
- 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
- 将工厂抽象成两层,AbsFactory(抽象工厂) 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
- 适用场景
1、客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
2、强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码
3、提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现
◆不可以增加产品,可以增加产品族!
//工厂接口
public interface IProductFactory {
//生产手机
IphoneProduct iphoneproduct();
//生产路由器
IrouterProject irouterproject();
}
//华为工厂
public class HuaweiFactory implements IProductFactory {
@Override
public IphoneProduct iphoneproduct() {
return new HuaweiPhone();
}
@Override
public IrouterProject irouterproject() {
return new HuaweiRouter();
}
}
//小米工厂
public class XiaomiFactory implements IProductFactory {
@Override
public IphoneProduct iphoneproduct() {
return new XiaomiPhone();
}
@Override
public IrouterProject irouterproject() {
return new XiaomiRouter();
}
}
//手机接口
public interface IphoneProduct {
void start();
void shutdown();
void callup();
void sendSMS();
}
//华为手机
public class HuaweiPhone implements IphoneProduct {
@Override
public void start() {
System.out.println("开启华为手机");
}
@Override
public void shutdown() {
System.out.println("关闭华为手机");
}
@Override
public void callup() {
System.out.println("华为打电话");
}
@Override
public void sendSMS() {
System.out.println("华为发信息");
}
}
//小米手机
public class XiaomiPhone implements IphoneProduct {
@Override
public void start() {
System.out.println("开启小米手机");
}
@Override
public void shutdown() {
System.out.println("关闭小米手机");
}
@Override
public void callup() {
System.out.println("小米打电话");
}
@Override
public void sendSMS() {
System.out.println("小米发信息");
}
}
//路由器接口
public interface IrouterProject {
void start();
void shutdown();
void openWife();
void setting();
}
//华为路由
public class HuaweiRouter implements IrouterProject {
@Override
public void start() {
System.out.println("开启华为路由器");
}
@Override
public void shutdown() {
System.out.println("关闭华为路由器");
}
@Override
public void openWife() {
System.out.println("打开华为wifi");
}
@Override
public void setting() {
System.out.println("华为设置");
}
}
//小米路由
public class XiaomiRouter implements IrouterProject {
@Override
public void start() {
System.out.println("开启小米路由器");
}
@Override
public void shutdown() {
System.out.println("关闭小米路由器");
}
@Override
public void openWife() {
System.out.println("打开小米 wifi");
}
@Override
public void setting() {
System.out.println("小米设置");
}
}
抽象工厂可以解决一系列的产品生产的需求,对于大批量,多系列的产品,用抽象工厂可以更好的管理和扩展;
三种工厂方式总结:
1、对于简单工厂和工厂方法来说,两者的使用方式实际上是一样的,如果对于产品的分类和名称是确定的,数量是相对固定的,推荐使用简单工厂模式;
2、抽象工厂用来解决相对复杂的问题,适用于一系列、大批量的对象生产;
应用场景:
◆JDK中Calendar的getlnstance方法(简单工厂模式)
◆JDBC中的Connection对象的获取
◆Spring中IOC容器创建管理bean对象.反射中Class对象的newInstance方法