1 工厂模式
作用
实现了创建者和调用者的分离
分类:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
原则:
- 开闭原则:一个软件的实体应当对扩展开放,对修改关闭
- 依赖倒置原则: 要针对接口编程,不用针对实现编程
- 迪米特法原则:只与你直接的朋友通信,而避免和陌生人通信
1.1 工厂模式核心本质
实例化对象不使用new,用工厂方法代替
将选择实现类,创建对象统一管理和控制。从而将调用者跟我们的实现类解耦
1.2 工厂的三种模式
- 简单工厂模式
用来生产同一等级结构中的任意产品(对于增加新的产品,需要求改已有代码) - 工厂方法模式
用来生产同一等级结构中的固定产品(支持增加任意产品) - 抽象工厂模式
围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂
1.3 简单工厂模式
- 定义汽车接口
package com.jialidun.gof.factory.simple;
public interface Car {
void name();
}
- 所有的汽车按汽车接口来实现
五菱汽车
package com.jialidun.gof.factory.simple;
public class WuLing implements Car{
@Override
public void name() {
System.out.println("五菱宏光!");
}
}
特斯拉汽车
package com.jialidun.gof.factory.simple;
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉!");
}
}
- 汽车工厂专门生产车
package com.jialidun.gof.factory.simple;
//静态工厂模式
//增加一个新的产品,如果你不修改代码,做不到的!
//开闭原则 Open Close Principle
public class CarFactory {
//方式一
public static Car getCar(String car){
if(car.equals("五菱")){
return new WuLing();
}else if(car.equals("特斯拉")){
return new Tesla();
}else {
return null;
}
}
//方式二
public static Car getWuling(){
return new WuLing();
}
public static Car getTesla(){
return new Tesla();
}
}
- 消费者到工厂买车
package com.jialidun.gof.factory.simple;
public class Consumer {
public static void main(String[] args) {
//接口,所有的实现类!
/*
//传统做法我们都是直接去new 汽车类
Car car1 = new WuLing();
Car car2 = new Tesla();
car1.name();//五菱宏光!
car2.name();//特斯拉!
*/
Car car1 = CarFactory.getCar("五菱");
Car car2 = CarFactory.getCar("特斯拉");
car1.name();
car2.name();
}
}
这样做还是有些问题,比如我要买一辆大众,那么汽车工厂就要添加大众的方法,需要修改代码,为了遵循开闭原则,由此衍生出工厂方法模式
1.4 工厂方法模式
创建一个汽车工厂接口,然后让五菱工厂、特斯拉工厂按汽车工厂接口去实现,这样我们就遵循了开闭原则
- 创建汽车工厂接口
package com.jialidun.gof.factory.method;
public interface CarFactory {
Car getCar();
}
- 让所有每个汽车工厂按汽车工厂接口去实现
五菱工厂
package com.jialidun.gof.factory.method;
public class WulingFactory implements CarFactory {
@Override
public Car getCar() {
return new WuLing();
}
}
特斯拉工厂
package com.jialidun.gof.factory.method;
public class TeslaFactory implements CarFactory{
@Override
public Car getCar() {
return new Tesla();
}
}
汽车接口
package com.jialidun.gof.factory.method;
public interface Car {
void name();
}
让所有汽车都按汽车接口去实现
五菱
package com.jialidun.gof.factory.method;
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱宏光!");
}
}
特斯拉
package com.jialidun.gof.factory.method;
public class Tesla implements Car {
@Override
public void name() {
System.out.println("特斯拉!");
}
}
消费者只需到工厂买车
package com.jialidun.gof.factory.method;
import com.jialidun.gof.factory.simple.CarFactory;
public class Consumer {
public static void main(String[] args) {
Car car1 = new MoBaiFactory().getCar();
Car car2 = new TeslaFactory().getCar();
Car car3 = new WulingFactory().getCar();
car1.name();
car2.name();
car3.name();
}
}
如果需要大众汽车,只需创建大众汽车工厂去实现汽车工厂接口,汽车类实现汽车接口即可,对原先的代码不用做任何改变。
1.5 抽象工厂模式
定义:
抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无序指定它们具体的类
适用场景
- 客户端(应用层) 不依赖于产品类实例如何被创建、实现等细节
- 强调一系列相关的产品对象(属于同一产品族)一起适用创建对象需要大量的重复代码
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现
优点:
- 具体产品在应用层的代码隔离,无需关心创建的细节
- 将一个系列的产品统一到一起创建
缺点:
- 规定了所有可能被创建的产品集合,产品簇中扩展新的产品困难;
- 增加了系统的抽象性和理解
UML类图
抽象工厂模式
创建一个手机产品接口
package com.jialidun.gof.factory.abstract1;
//手机产品接口
public interface IphoneProduct {
void start();
void shutdown();
void call();
void sendMsg();
}
创建路由器产品接口
package com.jialidun.gof.factory.abstract1;
//路由器产品接口
public interface IRouterProduct {
void start();
void shutdown();
void openWifi();
void setting();
}
创建产品工厂接口:负责生产手机产品,路由器产品
package com.jialidun.gof.factory.abstract1;
//抽象产品工厂
public interface IProductFactory {
//生产手机
IphoneProduct iphoneProduct();
//生产路由器
IRouterProduct iRouterProduct();
}
创建小米手机
package com.jialidun.gof.factory.abstract1;
//小米手机
public class XiaomiPhone implements IphoneProduct{
@Override
public void start() {
System.out.println("小米手机开机");
}
@Override
public void shutdown() {
System.out.println("关闭小米手机");
}
@Override
public void call() {
System.out.println("小米打电话");
}
@Override
public void sendMsg() {
System.out.println("小米发短信");
}
}
创建小米路由器
package com.jialidun.gof.factory.abstract1;
//小米路由器
public class XiaomiRouter implements IRouterProduct{
@Override
public void start() {
System.out.println("启动小米路由器");
}
@Override
public void shutdown() {
System.out.println("关闭小米路由器");
}
@Override
public void openWifi() {
System.out.println("启动小米WiFi");
}
@Override
public void setting() {
System.out.println("设置小米路由器");
}
}
创建华为手机
package com.jialidun.gof.factory.abstract1;
//华为手机
public class HuaweiPhone implements IphoneProduct{
@Override
public void start() {
System.out.println("华为手机开机");
}
@Override
public void shutdown() {
System.out.println("华为手机关机");
}
@Override
public void call() {
System.out.println("华为手机打电话");
}
@Override
public void sendMsg() {
System.out.println("华为手机发短信");
}
}
创建华为路由器
package com.jialidun.gof.factory.abstract1;
//华为路由器
public class HuaweiRouter implements IRouterProduct{
@Override
public void start() {
System.out.println("启动华为路由器");
}
@Override
public void shutdown() {
System.out.println("关闭华为路由器");
}
@Override
public void openWifi() {
System.out.println("启动华为WiFi");
}
@Override
public void setting() {
System.out.println("设置华为路由器");
}
}
创建小米工厂
package com.jialidun.gof.factory.abstract1;
public class XiaomiFactory implements IProductFactory{
@Override
public IphoneProduct iphoneProduct() {
return new XiaomiPhone();
}
@Override
public IRouterProduct iRouterProduct() {
return new XiaomiRouter();
}
}
创建华为工厂
package com.jialidun.gof.factory.abstract1;
public class HuaweiFactory implements IProductFactory{
@Override
public IphoneProduct iphoneProduct() {
return new HuaweiPhone();
}
@Override
public IRouterProduct iRouterProduct() {
return new HuaweiRouter();
}
}
客户端
package com.jialidun.gof.factory.abstract1;
public class Client {
public static void main(String[] args) {
System.out.println("======小米产品=======");
//小米工厂
IphoneProduct iphoneProduct = new XiaomiFactory().iphoneProduct();
iphoneProduct.call();
iphoneProduct.sendMsg();
IRouterProduct iRouterProduct = new XiaomiFactory().iRouterProduct();
iRouterProduct.openWifi();
System.out.println("=====华为产品=====");
IphoneProduct huaweiPhone = new HuaweiFactory().iphoneProduct();
huaweiPhone.start();
huaweiPhone.sendMsg();
IRouterProduct huaweiRouter = new HuaweiFactory().iRouterProduct();
huaweiRouter.setting();
}
}