GoF之简单工厂、工厂方法、抽象工厂详解

工厂模式分为:简单工厂 工厂方法 抽象工厂

实现了创建者和调用者的分离。
面向对象设计的基本原则:
OCP(开闭原则,Open-Closed Principle):一个软件的实体应当对扩展开放,对修改关闭
DIP(依赖倒转原则,Dependence InversionPrinciple):要针对接口编程,不要针对实现编程
LoD(迪米特法则,Law of Demeter):只与你直接的朋友通信,而避免和陌生人通信
本质:
实例化对象,用工厂方法代替new操作。
将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。
具体类别及实现:
简单工厂(SimplenessFactory)模式
也称为静态工厂,用来生产同一等级结构中的任意产品。(缺点:对于增加新的产品,需要修改已有代码,比较常用)
//创建一个产品(车)的接口,其他具体品牌车都实现此接口
//不同类型车具有不同的运行车速
public interface Car{
public void run();
}

public class Audi implements Car{
@Override
public void run(){
System.out.println(“奥迪在跑!”);
}
}

public class Byd implements Car{
@Override
public void run(){
System.out.println(“比亚迪在跑!”);
}
}
//需要在工厂类中进行判断,根据客户端自动判断需要生产的类型车
//如果要添加新类型车,只能修改原有的代码,既增加实现类,又需要增加分支判断,同时增加客户端输入,违反开闭原则
public class CarFactory{
public static CarcreatCar(String type){
Carc = null;
if(“奥迪”.equals(type)){
c= new Audi();
}
if(“比亚迪”.equals(type)){
c= new Byd();
}
return c;
}
}
//客户端不用关心创建过程,只需要根据需求类别调用方法即可
public class Client{
public static void main(String[] args) {
Carcar1 = CarFactory.creatCar(“奥迪”);
Carcar2 = CarFactory.creatCar(“比亚迪”);
car1.run();
car2.run();
}
}
工厂方法(FactoryMethod)模式
定义一个用于创建产品的接口,由子类决定生产什么产品。用来生产同一等级结构中的固定产品。(支持增加任意产品,遵循了开闭原则,每次有新的车加入,只需添加一个新的工厂类即可,无需修改原有的代码,缺点:产品一多,类也不断增多了,不好管理)
//创建一个产品(车)的接口,其他具体品牌车都实现此接口,不同类型车具有不同的运行
public interface Car {
public void run();
}

public class Audi implements Car{
@Override
public void run() {
System.out.println(“奥迪在跑!”);
}
}

public class Byd implements Car{
@Override
public void run() {
System.out.println(“比亚迪在跑!”);
}
}
//定义一个工厂的共同接口,每个类型车都实现工厂接口
//每个工厂实现类去生产各自的类型车,每次有新的产品,只需添加一个新的实现类即可,无需修改原有代码
public interface CarFactory {
CarcreatCar();
}

public class AudiFactory implements CarFactory{
@Override
public Car creatCar() {
return new Audi();
}
}

public class BydFactory implements CarFactory{
@Override
public Car creatCar() {
return new Byd();
}
}
//当各类工厂创建完之后,使用哪个工厂,只需要在客户端进行选择即可
//如果增加了新工厂类,客户端只需要增加新工厂类的实例。客户端的实例决定生产哪个产品
public class Client{
public static void main(String[] args) {
CarFactorycarFactory1 = new AudiFactory();
Carcar1 = carFactory1.creatCar();

    CarFactorycarFactory2 = new BydFactory();
    Carcar2 = carFactory2.creatCar();
     
    car1.run();
    car2.run();
}  

}
抽象工厂(AbstractFactory)
提供一个创建产品族的接口,每个子类都可以生产其产品族相关的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
抽象工厂模式如下:
//发动机接口
public interfaceEngine {
void run();
void start();
}

//高端发动机
public classHighEngine implements Engine {
@Override
public void run() {
System.out.println(“转速快”);
}

@Override
public void start() {
   System.out.println("启动快");
}

}

//低端发动机
public classLowEngine implements Engine {
@Override
public void run() {
System.out.println(“转速慢”);
}
@Override
public void start() {
System.out.println(“启动慢”);
}
}

//座椅接口
public interfaceSeat {
void comfort();
}

//高端座椅
public classHighSeat implements Seat {
@Override
public void comfort() {
System.out.println(“舒适度好”);
}
}

//低端座椅
public classLowSeat implements Seat {
@Override
public void comfort() {
System.out.println(“舒适度差”);
}
}

//轮胎接口
public interfaceTyre {
void wear();
}

//高端轮胎
public classHighTyre implements Tyre {
@Override
public void wear() {
System.out.println(“耐磨性好”);
}
}

//低端轮胎
public classLowTyre implements Tyre {
@Override
public void wear() {
System.out.println(“耐磨性差”);
}
}
//汽车工厂接口
public interfaceCarFactory {
//制造发动机方法
Engine createEngine();
//制造座椅方法
Seat createSeat();
//制造轮胎方法
Tyre createTyre();
}
//高端汽车工厂
public classHighCarFactory implements CarFactory {
@Override
public Engine createEngine() {
return new HighEngine();
}
@Override
public Seat createSeat() {
return new HighSeat();
}
@Override
public Tyre createTyre() {
return new HighTyre();
}
}
//低端汽车工厂
public classLowCarFactory implements CarFactory {
@Override
public Engine createEngine() {
return new LowEngine();
}

@Override
public Seat createSeat() {
    return new LowSeat();
}

@Override
public Tyre createTyre() {
    return new LowTyre();
}

}

//客户端
public class Client{
public static void main(String[] args) {
//生产高端汽车
CarFactory hFactory = newHighCarFactory();
Engine he = hFactory.createEngine();
Seat hs = hFactory.createSeat();
Tyre ht = hFactory.createTyre();
//生产低端汽车
CarFactory lFactory = newLowCarFactory();
Engine le = lFactory.createEngine();
Seat ls = lFactory.createSeat();
Tyre lt = lFactory.createTyre();
//也可以根据情况将三个部分高低端混合生产产品
}
}
上面的抽象工厂模式是最优了吗?NO,将简单工厂模式和抽象工厂模式结合起来,对上面的抽象工厂改进简化,如下:
//发动机接口
public interfaceEngine {
void run();
void start();
}

//高端发动机
public classHighEngine implements Engine {
@Override
public void run() {
System.out.println(“转速快”);™
}

@Override
public void start() {
   System.out.println("启动快");
}

}

//低端发动机
public classLowEngine implements Engine {
@Override
public void run() {
System.out.println(“转速慢”);
}

@Override
public void start() {
   System.out.println("启动慢");
}

}

//座椅接口
public interfaceSeat {
void comfort();
}

//高端座椅
public classHighSeat implements Seat {
@Override
public void comfort() {
System.out.println(“舒适度好”);
}
}

//低端座椅
public classLowSeat implements Seat {
@Override
public void comfort() {
System.out.println(“舒适度差”);
}
}

//轮胎接口
public interfaceTyre {
void wear();
}

//高端轮胎
public classHighTyre implements Tyre {
@Override
public void wear() {
System.out.println(“耐磨性好”);
}
}

//低端轮胎
public classLowTyre implements Tyre {
@Override
public void wear() {
System.out.println(“耐磨性差”);
}
}

class Production{
private static String product = 高端;
//private static String product = 低端;
publicstatic Engine createEngine(){
Engineengine = null;
switch(db){
case “高端”:
engine= new HighEngine();
break;
case “低端”:
engine= new LowEngine();
break;
}
returnengine;
}
publicstatic Seat createSeat(){
Seatseat = null;
switch(db){
case “高端”:
seat= new HighSeat();
break;
case “低端”:
seat= new LowSeat();
break;
}
returnseat;
}
publicstatic Tyre createTyre(){
Tyretyre = null;
switch(db){
case “高端”:
tyre= new HighTyre();
break;
case “低端”:
tyre= new LowTyre();
break;
}
returntyre;
}
}
//客户端没有出现任何HighEngine、LowEngine等字样,客户端只需要.createEngine()、.createSeat()等就可以获得实例。
//达到生产与消费完全解耦的目的,当更换产品族时,只需要更改服务端product字段
public class Client{
public static void main(String[] args) {
Engine le = Production.createEngine();
Seat ls = Production.createSeat();
Tyre lt = Production.createTyre();
}
}
所有用简单工厂的地方,都可以考虑用反射技术来去除switch或if,解除分支判断带来的耦合。下面模仿IOC容器原理,利用反射+配置再次对Production改进,如下:
class Production{
//将属性(High或Low)以键值对配置到config.propertis中,再以流读取配置
//spring-boot-starter会自动加载yml文件(application.yml)
//如果配置在该yml中,可以省略配置文件加载,用@ConfigurationProperties(prefix =“configpro”)注入
InputStreamin = new BufferedInputStream(newFileInputStream(“config.propertis”));
Propertispro =new Propertis();
pro.load(in);
//product变量的值通过配置获取(High或Low)
private static String product =pro.getProperty(“product”);
//private static String product = Low;
public static Engine createEngine(){
//通过反射获取对象实例
class instance =(product+Engine).Class;
return (Engine)instance.newInstance;
}
public static Seat createSeat(){
class instance = (product+Seat).Class;
return (Seat)instance.newInstance;
}
public static Tyre createTyre(){
class instance = (product+Tyre).Class;
return (Tyre)instance.newInstance;
}
}
通过配置+反射的方式,只需要更改配置就能实现产品族的更换。

更多技术分享,微信搜索公众号“专注一行代码”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值