工厂模式【创建型模式之一】

工厂模式

  在java中,万物皆对象,这些对象的创建我们常用new来实现,方式比较简单,但是这种方式创建对象会使代码的耦合度比较高,如果要修改代码,那么我们需要重新再把所有的对象再new一遍,这是相当麻烦的事情,且不符合软件设计的开闭原则。如果使用工厂来代替我们自己创建对象,我们只需要跟工厂打交道就可以了,彻底和对象解耦,该模式有如下几种。

1 简单工厂模式

  实际上简单工厂模式不算是一种设计模式,更像一种编程习惯,因其结构/角色简单明了而命名。简单工厂包含如下角色:

  • 抽象产品:定义产品的规范
  • 具体产品:实现或者继承抽象产品的子类
  • 具体工厂:提供了创建产品的方法,通过该方法来获取产品对象

实现代码如下
1.抽象产品

public interface Car{
    void name();
}

2.具体产品

//WuLing.java
public class WuLing implements Car{
    @Override
    public void name() {
        System.out.println("五菱");
    }
}
//DaZhong.java
public class DaZhong implements Car{
	@Override
    public void name() {
        System.out.println("大众");
    }
}
//TesLa.java
public class TesLa implements Car{
	@Override
    public void name() {
        System.out.println("特斯拉");
    }
}

3.简单工厂

public class SimpleFactory{
	//方式1(不常用)
	public Car getCar(String car){
		if ("五菱".equals(car)) {
            return new WuLing();
        } else if ("特斯拉".equals(car)) {
            return new TesLa();
        } else if ("大众".equals(car)) {
            return new DaZhong();
        } else {
            return null;
        }
	}
	//方式2(常用)
	public static Car getWuLing() {
        return new WuLing();
    }
    public static Car getDaZhong() {
        return new DaZhong();
    }
    public static Car getTesLa() {
        return new TesLa();
    }
}

4.优缺点
优点:

  • 封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,这样以后就避
  • 免了修改客户代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,这样就降低了客户
  • 代码修改的可能性,更加容易扩展

缺点:

  • 增加新产品时还是要修改工厂类的代码,违背了“开闭原则”。

5.扩展
  可以把工厂类的方法改为静态方法,这样就不需要手动new创建工厂类对象

public class SimpleFactory{
	//方式1(不常用)
	public static Car getCar(String car){
		if ("五菱".equals(car)) {
            return new WuLing();
        } else if ("特斯拉".equals(car)) {
            return new TesLa();
        } else if ("大众".equals(car)) {
            return new DaZhong();
        } else {
            return null;
        }
	}
	...
}

2 工厂方法模式

1.概念:定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。使用工厂方法模式完美解决了违背开闭原则问题

2.本质:每一个产品对应自己的工厂(工厂用于生成该产品),这些工厂实现或者继承顶层的抽象工厂

3.结构:(角色)

  • 抽象工厂:提供创建产品的接口(实际上就是方法),调用者通过访问具体工厂的方法来创建具体产品
  • 具体工厂:主要实现抽象工厂中的抽象方法,完成具体的产品创建
  • 抽象产品:定义了产品的规范,描述产品的特性和功能
  • 具体产品:实现列抽象产品所定义的方法,由具体工厂来创建,它同具体工厂之间一一对应。

4.代码实现
4.1 抽象产品

public interface Car {
    void name();
}

4.2 具体产品

//WuLing.java
public class WuLing implements Car{
    @Override
    public void name() {
        System.out.println("五菱");
    }
}
//TesLa.java
public class TesLa implements Car{
	@Override
    public void name() {
        System.out.println("特斯拉");
    }
}

4.3 抽象工厂

public interface CarFactory {
    Car getCar();
}

4.4 具体工厂

//五菱具体工厂
public class WuLingFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new WuLing();
    }
}
//特斯拉具体工厂
public class TesLaFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new TesLa();
    }
}

备注:调用者想要创建哪个对象,就调用对应的具体工厂的方法即可,如果想要添加新的具体产品,只需要添加对象的具体工厂和具体产品即可,不需要修改源代码,符合软件开发的开闭原则,但存在一个问题:这样会导致系统复杂,当产品过多时会产生类爆炸

3 抽象工厂方法模式

  抽象工厂方法模式是工厂方法模式的升级版,其弥补了工厂方法只生成一种产品的限制,抽象工厂方法模式可以生产不同等级的产品,不同品牌的产品。(不同品牌<=>不同产品族,不同等级产品<=>不同级别产品)
本质:是围绕一个超级工程创建其他工厂,该超级工厂又称为其他工厂的工厂,这个超级工厂中定义所要生产的不同的产品等级的顶级接口
在这里插入图片描述

结构

  • 抽象工厂:提供创建产品的接口,包含多个创建产品的方法,可以创建不同等级的多个产品
  • 具体工厂:主要实现抽象工厂中的多个抽象方法,完成具体的产品创建
  • 抽象产品:定义产品的规范,描述产品的特性和功能,可以有多个抽象产品
  • 具体产品:实现抽象产品所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系

实现
1.抽象产品1

//抽象产品-手机
public interface IPhoneProduct {
    void meg();
}

2.抽象产品2

//抽象产品-路由器
public interface IRouterProduct {
    void msg();
}

3.具体产品-小米手机

public class XiaoMiIphone implements IPhoneProduct{
    @Override
    public void meg() {
        System.out.println("小米手机");
    }
}

4.具体产品-小米路由器

public class XiaoMIRouter implements IRouterProduct{
    @Override
    public void msg() {
        System.out.println("小米路由");
    }
}

5…抽象工厂-包含多个抽象产品的接口

public interface ProductFactory {
    IPhoneProduct getIPhone();

    IRouterProduct getIRouter();
}

6.具体工厂1-小米工厂

public class XiaoMiFactory implements ProductFactory{
    @Override
    public IPhoneProduct getIPhone() {
        return new XiaoMiIphone();
    }

    @Override
    public IRouterProduct getIRouter() {
        return new XiaoMIRouter();
    }
}

7.具体工厂2-华为工厂

//同上

8.测试类

public class Test {
    public static void main(String[] args) {
        XiaoMiFactory xiaoMiFactory = new XiaoMiFactory();
        IPhoneProduct iPhone = xiaoMiFactory.getIPhone();
        iPhone.meg();
    }
}

备注:需要什么品牌系列的产品,只需要添加相应的具体工厂和具体产品类即可,不需要修改源代码,符合开闭原则
但如果新增的是产品结构等级,比如新增一个电视机,那么显示是要修改源代码且要修改顶层接口的源代码,这显然是不符合开闭原则的,因此该模式非常适合添加一个族系列相关产品。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值