java工厂设计模式

工厂设计模式概述:

实现了创建者与调用者的分离,即将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

其实设计模式和面向对象设计原则都是为了使得 开发项目更加容易扩展和维护,解决方式就是一个“分工”。随着社会的发展,分工也越来越细。

原始社会的人,人什么都要会,自己种吃的,自己打猎,自己冷了,薅羊毛织衣服,自己治病等。现在社会出现了很多工厂,制造衣服的,制造食物的工厂,制造工具的工厂等。

首先我们看一下无工厂的模式:

在这里插入图片描述
上面代码在main方法所在的类中,创建者也是在此类中,如new BYD(),而调用者也在此类中,如a.run();即在次类中没有实现创建者和调用者的分离,既体现了创建又体现了调用,混在一起了。

简单工厂模式(不属于23种设计模式,相当于一个综合工厂):

简单工厂也叫静态工厂,就是工厂类一般使用静态方法,通过接受的参数的不同来返回不同的实例对象。

缺点:对于增加新产品,不修改代码的话,是无法扩展的。违反了开闭原则(对外扩展开放,对修改封闭)。比如你在工厂中准备一个新的车的品种宝马的话,就要修改工厂类中的代码。则破坏了代码。违反了开闭原则。

代码演示简单工厂模式:

package com.fan.domain3;

//第三步:调用者
public class CarTest {
    public static void main(String[] args) {
        //这里只体现独立的调用者
        Car audi = CarFactory.getCar("奥迪");
        audi.run();
        Car byd = CarFactory.getCar("比亚迪");
        byd.run();
    }

}
//第一步:设计通用接口和两个实现类
interface Car{
    void run();
}

//实现车的接口。这里相当于奥迪车图纸
class Audi implements Car {

    public void run() {
        System.out.println("奥迪在跑");
    }
}

//实现车的接口,这里是比亚迪汽车图纸
class BYD implements Car{

    public void run() {
        System.out.println("比亚迪在跑");
    }
}

//第二步:专门设计 一个工厂类 去制造汽车
//factory只是体现一个创建者。而不是调用者(使用者/消费者)
class CarFactory {
    //方式一
    public static Car getCar(String type){//传入汽车类型
        if("奥迪".equals(type)){
            return new Audi();//new 一个奥迪车
        }else if("比亚迪".equals(type)){
            return new BYD();//new 一个比亚迪车
        }else{
            return null;
        }
    }

    //方式二:

   /* public static Car getAudi(){
        return  new Audi();
    }

    public static Car getBYD(){
        return  new BYD();
    }*/

}

图示:

在这里插入图片描述
总结:
这就是简单工厂方法,只有一个工厂类(一个大综合工厂)来面向多个目标实现。当目标实现增多时,我们不得不去修改工厂类的方法,使其兼容新的实现类型,这明显违背了开闭原则,所以出现了工厂方法模式。

工厂方法模式(属于23种设计模式,相当于多个细分的工厂):

工厂方法模式是对简单工厂模式的抽象升级,将工厂这个概念抽象出来成为接口,然后针对每种目标实现类创建一个工厂实现(细分工厂),一对一来实现,当新增了目标实现,只要同时新增一个工厂实现即可。

代码演示:

package com.fan.domain3;

//第三步:调用者
public class CarTest {
    public static void main(String[] args) {
        //这里只体现独立的调用者,
        //创建工厂实例,然后调用工厂造汽车的方法
        Car audi = new AudiFactory().getCar();
        audi.run();
        Car byd = new BydFactory().getCar();
        byd.run();
    }

}
//第一步:设计通用接口和两个实现类
interface Car{
    void run();
}

//实现车的接口。这里相当于奥迪车图纸
class Audi implements Car {

    public void run() {
        System.out.println("奥迪在跑");
    }
}

//实现车的接口,这里是比亚迪汽车图纸
class BYD implements Car{

    public void run() {
        System.out.println("比亚迪在跑");
    }
}

//第二步:专门设计一个工厂的接口 和 具体的实现类工厂(细分工厂了)
interface CarFactory {
    Car getCar();//车的工厂是专门用来获取汽车的。这是车工厂的规范
}

//接口就是用来被实现的,则下来我们需要有工厂接口的实现类  具体的工厂实现类
//奥迪汽车制造厂
class AudiFactory implements CarFactory {

    public Car getCar() {//返回值类型也可以是Audi
        return new Audi();
    }
}
//BYD汽车制造厂
class BydFactory implements CarFactory {

    public Car getCar() {//返回值类型也可以是BYD
        return new BYD();
    }
}

在这里插入图片描述

四、解析:

从上面的实例中可以很容易看出来,工厂方法模式的重点就在这个工厂接口了

目标可以无限扩展,工厂类也要随之扩展,一对一存在,满足了开闭原则,但如果目标实现较多,工厂实现类也会增多,不简洁

MyBatis中使用的比较多,事务模块和数据源模块都使用了工厂方法模式。

总结:

简单工厂模式与工厂方法模式真正的避免了代码的改动了吗,并没有。在简单工程模式中,新产品的加入要修改工厂角色中的判断语句;而在工厂方法模式中,要么将逻辑留在抽象工厂角色中,要么在客户端程序中将具体工厂角色写死(就像上面的例子一样,同样需要改代码从而来增加新工厂)。而且产品对象创建条件的改变必然会引起工厂角色的修改。
面对这种情况,java的反射机制与配置文件的巧妙结合突破了限制–这在spring中完美的体现出来。

抽象工厂模式 (属于23种设计模式)

定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

抽象工厂与工厂方法的区别,就在于产品簇的问题,多了一种产品,这时候怎么办呢,就是在接口类里面加上创建大炮的方法,然后每个车间就可以有两个子车间分别来生产汽车和大炮。这样的话缺点也很显然的冒了出来,如果我又想生产飞机,那么我要需要更改所有的工厂车间以及工厂接口。

抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。

代码演示:

package com.fan.domain3;

//第三步:调用者
public class FactoryTest {
    public static void main(String[] args) {
        //这里只体现独立的调用者,
        Car byd = new FactoryTwo().getCarByFactory();
        byd.run();
        Plane airPlan = new FactoryOne().getPlanByFactory();
        airPlan.getPlane();
    }

}
//第一步:设计第一个产品接口和两个实现类
interface Car{//车接口
    void run();
}

//实现车的接口,这里相当于奥迪车图纸
class Audi implements Car {

    public void run() {
        System.out.println("奥迪在跑");
    }
}

//实现车的接口,这里是比亚迪汽车图纸
class BYD implements Car{

    public void run() {
        System.out.println("比亚迪在跑");
    }
}

//第二步:设计第二个产品接口 和 两个实现类
interface Plane {//飞机 接口
    void getPlane();
}

class AirPlane implements Plane {

    public void getPlane() {
        System.out.println("客机在飞");
    }
}

class BattlePlane implements Plane {

    public void getPlane() {
        System.out.println("战斗机在飞");
    }
}

//第三步:抽象工厂接口 及  具体工厂实现类
interface Factory {
    Car getCarByFactory();//
    Plane getPlanByFactory();
}

//具体工厂类 1:可以生产奥迪 和 客机
class FactoryOne implements Factory {

    public Car getCarByFactory() {
        return new Audi();//生产奥迪
    }

    public Plane getPlanByFactory() {
        return new AirPlane();//生产客机
    }
}

//具体工厂类 2:可以生产比亚迪 和 战斗机
class FactoryTwo implements Factory {

    public Car getCarByFactory() {
        return new BYD();
    }

    public Plane getPlanByFactory() {
        return new BattlePlane();
    }
}

运行结果;
比亚迪在跑
客机在飞

总结:抽象工厂模式的用意是: 给客户端提供一个接口,可以创建多个产品族中的产品对象。

而且使用抽象工厂模式还要满足一定条件:

1.系统中有多个产品族,而系统一次只可能消费其中一族产品。
2. 同属于同一个产品族的产品一起使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值