博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
工厂模式
阅读量:3909 次
发布时间:2019-05-23

本文共 5608 字,大约阅读时间需要 18 分钟。

简单工厂模式

为什么要有简单工厂?

方法是一片代码的封装,当方法功能升级的时候,直接去改方法中的代码,所有调用此方法名的都会产生改变,而不是找到找到每一处的那个不使用方法的一行行功能实现,一个个改,,,这样一算得多麻烦。

简单工厂也是这个理,需要的对象都来我这里拿吧,你要使用直接调用我方法即可,我给你返回对象出来。我给你创建,我给你返回对象,

你找我拿对象即可,当以后要需要添加对象,或是修改,这就方便了,你谁也不用找,找到我简单工厂一改,所有调用我此方法获得对象的都改变了,方便,简介。

我让你不依赖对象的创建,因为你一改动,这后果很麻烦,

达到这种不依赖的目的,这就是简单工厂
——————————————————————————————————————————————————————
简单工厂模式,又称静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
第一步:建立一个抽象产品接口
第二步:建立需要的具体产品类
第三部:用一个swtich语句来调用你所需要的具体产品(简单工厂)
具体代码:

抽象类接口

public interface CarType {    void GetCar();}

//具体产品类

public class SportCar implements  CarType{    public void GetCar() {        System.out.println("跑车");    }}
public class JeepCar implements CarType {    @Override    public void GetCar() {        System.out.println("吉普车");    }}

//简单工厂

public class Factory {    public static final int TYPE_SPORT = 1;//跑车    public static final int TYPE_JEEP = 2;//吉普    public Car GetCar(int carType) throws Exception {        switch (carType)        {            case Factory.TYPE_SPORT:                return new SportCar();            case Factory.TYPE_JEEP:                return new JeepCar();            default:                throw new Exception("爱上一匹野马,可我的家里没有草原. 你走吧!");        }    }}

//客户端

public class Client {    public static void main(String[] args) throws Exception {        Factory factory = new Factory();        factory.GetCar(Factory.TYPE_JEEP);    }}

缺点

1 扩展性差(我想增加一种车型,需要修改工厂类方法)

2 不同的产品需要不同额外参数的时候 不支持。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

工厂方法模式

上面提到简单工厂,在新增具体类型的时候回修改工厂,这不符合开闭原则(即对扩展开放——可以继承,对修改关闭——不能修改源代码)。而这时候就应该用工厂方法。

继续上面的例子,改写简单工厂为工厂方法:
第一步:增加一个抽象工厂类
第二部:增加这个抽象工厂的子工厂类

//抽象工厂接口

public interface TypeFactory {    CarType createCar();}

//具体工厂

public class JeepFactory implements TypeFactory {    @Override    publicstatic CarType createCar() {        return new JeepCar();    }}
public class SportFactory implements TypeFactory {    @Override    public static CarType createCar() {        return new SportCar();    }}

//客户

public class Client {    public static void main(String[] args) throws Exception {         TypeFactory sportFactory = new SportFactory();        CarType car = sportFactory.createCar();        car.GetCar();    }}

福利,第二种较好的方法

//工厂

public class TypeFactory {    public static CarType getCar(Class c) {        CarType car = null; //定义一个类型的车辆        try {            car = (CarType) Class.forName(c.getName()).newInstance(); //产生一个类型的车        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }        return car;    }}

//新增加车型

public class Trunks implements CarType{    @Override    public void GetCar() {        System.out.println("货车");    }}

//Client

public class Client {    public static void main(String[] args) throws Exception {        CarType trunks = TypeFactory.getCar(Trunk.class);        trunks.GetCar();    }}

这时候新增车型并不需要改工厂

番外篇之工厂方法的延迟始化

即一个对象初始化后不释放,等再次用到的啥时候直接那就可以了

public class CarFactory {
private static HashMap<String,Car> cars = new HashMap<String,Car>();

public static Car getCar(Class c) {    Car car = null; //定义一个类型的车辆    try {        if(cars.containsKey(c.getSimpleName())){            car = cars.get(c.getSimpleName());        }else{            car = (Car) Class.forName(c.getName()).newInstance();            //放到MAP中            cars.put(c.getSimpleName(), car);        }    } catch (InstantiationException e) {        e.printStackTrace();    } catch (IllegalAccessException e) {        e.printStackTrace();    } catch (ClassNotFoundException e) {        e.printStackTrace();    }    return car;}

}

这时新增产品只需添加新的具体工厂方法和具体产品不需要修改源代码。

缺点:一个产品产生一个工厂,如果产品太多则会管理不过来。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

抽象工厂模式

生产一辆车不可能光考虑车型,还要考虑颜色,形状,配件等等。如果继续按上面的工厂方法,那么就会产生大量的工厂 难以管理。这时候我们可通过抽象工厂来解决。

抽象工厂的思想是把有关联的产品放到一个工厂里面,这样一来大大降低了工厂类的维护。
继工厂方法的第二种代码
新增抽象类接口

public interface CarColor {    void GetColor();}

新增具体产品类

public class Yellow implements  CarColor{    public void GetColor() {        System.out.println("黄色");    }}
public class Black implements CarColor {    @Override    public void GetColor() {        System.out.println("黑色");    }}

新增抽象工厂接口

public interface ColorFactory {    CarColor createColor();}

为 Color 和 Type 对象创建抽象类来获取工厂。

public abstract class CarFactory {   public abstract CarColor getColor(Class color);   public abstract CarType getCar(Class type) ;}

//颜色工厂

public class ColorFactory extends CarFactory{    public CarColor getColor(Class c) {        CarColor car = null; //定义一个颜色        try {            car = (CarColor) Class.forName(c.getName()).newInstance(); //产生一个颜色        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }        return car;    }}

//将前面的这个代码方法改成非静态的,且继承抽象类

public class TypeFactory  extends CarFactory{    public  CarType getCar(Class c) {        CarType car = null; //定义一个类型的车辆        try {            car = (CarType) Class.forName(c.getName()).newInstance(); //产生一个类型的车        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }        return car;    }}

转载地址:http://uyfrn.baihongyu.com/

你可能感兴趣的文章
工作这几年所获、所感、所悟
查看>>
不想写脚本清理 mongodb 中的垃圾数据,ttlIndex 能帮到你!
查看>>
跟我一起学.NetCore之MediatR好像有点火
查看>>
.NET架构小技巧(4)——反射,架构人员法宝II
查看>>
让你变厉害的7个底层思维
查看>>
译 | 将数据从Cosmos DB迁移到本地JSON文件
查看>>
再被补刀!Flash又遭抛弃,你会怀念它吗?
查看>>
国产操作系统发展离不开人才和市场
查看>>
心想技术驱动业务,却在背道而驰
查看>>
SM2 国密算法被 Linux 内核社区接受
查看>>
日计不足涓滴成河-自定义响应结果格式化器
查看>>
.NET架构小技巧(3)——反射,架构人员法宝I
查看>>
对精致码农大佬的 [理解 volatile 关键字] 文章结论的思考和寻找真相
查看>>
.NET for Apache Spark 1.0 版本发布
查看>>
吐槽一下Abp的用户和租户管理模块
查看>>
. NET5正式版本月来袭,为什么说gRPC大有可为?
查看>>
初识ABP vNext(12):模块的独立运行与托管
查看>>
新版本 Swashbuckle swagger 组件中的 "坑"
查看>>
.NET架构小技巧(5)——反射,架构人员法宝III
查看>>
C# 中的 in 参数和性能分析
查看>>