【设计模式】工厂模式(定义 | 特点 | Demo入门讲解)

文章目录

其实工厂模式就是用一个代理类帮你创建管理对象,你就不用在代码层面去不断new对象的使用了。

创建对象和调用对象两者之间会解耦!

定义

工厂模式有三种:

  • 简单工厂模式
  • 工厂方法模式
  • 抽象方法模式

简单工厂模式

简单工厂模式也叫静态工厂模式。

举个例子:你要去买一台手机,你不用关心手机是怎么生产出来的,里面的零件具体又是怎么制造的,这些通通都交给工厂去处理,你尽管去买手机就好了。

案例 | 代码

Phone顶层接口设计
java 复制代码
/**
 * @author linghu
 * @date 2024/7/5 11:08
 */
public interface Phone {
    void getBrand();
}
Meizu品牌类
java 复制代码
/**
 * @author linghu
 * @date 2024/7/5 11:09
 */
public class Meizu implements Phone{
    @Override
    public void getBrand() {
        System.out.println("魅族");
    }
}
Xiaomi品牌类
java 复制代码
/**
 * @author linghu
 * @date 2024/7/5 12:35
 */
public class Xiaomi implements Phone{
    @Override
    public void getBrand() {
        System.out.println("小米");
    }
}
PhoneFactory工厂类

这个是简单工厂模式,又叫静态工厂,所以方法自然是静态的!而且这个工厂类负责帮我们创建对象,并且返回对象!

在这里我们可以先用硬编码的方式:

java 复制代码
/**
 * @author linghu
 * @date 2024/7/5 12:35
 */
public class PhoneFactory {
    public static Phone getPhone(String phone){
        if ("小米".equals(phone)){
            return new Xiaomi();
        } else if ("魅族".equals(phone)) {
            return new Meizu();
        }else {
            return null;
        }
    }
}
Customer 消费者类

这个类就类似一个客户端的作用把。

java 复制代码
/**
 * @author linghu
 * @date 2024/7/5 12:38
 */
public class Customer {
    public static void main(String[] args) {
        PhoneFactory.getPhone("小米").getBrand();
        PhoneFactory.getPhone("魅族").getBrand();
    }
}

工厂方法模式

工厂方法模式就是在上面简单工厂模式的基础上做了一些修改,具体的做法就是为每种不同品牌的手机都创建一个工厂独立生产。

案例 | 代码

如上,其他代码都不变,变化的部分是工厂那部分!

PhoneFactory工厂类

首先修改一下PhoneFactory工厂类,将:

java 复制代码
/**
 * @author linghu
 * @date 2024/7/5 12:35
 */
public class PhoneFactory {
    public static Phone getPhone(String phone){
        if ("小米".equals(phone)){
            return new Xiaomi();
        } else if ("魅族".equals(phone)) {
            return new Meizu();
        }else {
            return null;
        }
    }
}

修改为:

java 复制代码
/**
 * @author linghu
 * @date 2024/7/5 12:35
 */
public interface PhoneFactory {
     Phone getPhone();
}

新增的两个工厂类:

java 复制代码
/**
 * @author linghu
 * @date 2024/7/5 14:09
 */
public class MeizuFactory implements PhoneFactory{
    @Override
    public Phone getPhone() {
        return new Meizu();
    }
}
/**
 * @author linghu
 * @date 2024/7/5 14:08
 */
public class XiaomiFactory implements PhoneFactory{
    @Override
    public Phone getPhone() {
        return new Xiaomi();
    }
}

Customer 消费者类:

java 复制代码
/**
 * @author linghu
 * @date 2024/7/5 12:38
 */
public class Customer {
    public static void main(String[] args) {
//        PhoneFactory.getPhone("小米").getBrand();
//        PhoneFactory.getPhone("魅族").getBrand();
        Phone xiaomi=new XiaomiFactory().getPhone();
        Phone meizu=new MeizuFactory().getPhone();
        xiaomi.getBrand();
        meizu.getBrand();
    }
}

Java高级特性---工厂模式与反射的高阶玩法

我们先回顾一下上面的工厂模式用法,列举一下会发现:

  • 简单工厂模式的局限性在于:如果我们扩充手机的品牌,就会违反 开闭原则
  • 工厂方法模式的局限性在于:我们扩充手机品牌需要不断new更多对象 ,这是耦合的最大元凶!!
方案:反射+工厂模式

PhoneFactory工厂类

java 复制代码
/**
 * @author linghu
 * @date 2024/7/5 12:35
 */
public class PhoneFactory {
    public static Phone getInstance(String origin) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class<?> cls = Class.forName("com.linghu.factory." + origin);
        Phone brand=(Phone)cls.newInstance();
        return brand;
    }
}

Customer 消费者类

这个时候我们无需再new更多对象了,也不用写死了:

java 复制代码
/**
 * @author linghu
 * @date 2024/7/5 12:38
 */
public class Customer {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//        PhoneFactory.getPhone("小米").getBrand();
//        PhoneFactory.getPhone("魅族").getBrand();
//        Phone xiaomi=new XiaomiFactory().getPhone();
//        Phone meizu=new MeizuFactory().getPhone();
//        xiaomi.getBrand();
//        meizu.getBrand();
        PhoneFactory.getInstance("Xiaomi").getBrand();
    }
}

输入类名以后,反射创建对象,再通过工厂返回相关对象!!

总结

第一个静态工厂模式:在实际去开发中会发现比较常用,尽管上面讲了不符合(面向对象)OOP原则。
第二个工厂方法模式:不修改工厂类的前提,也就是说不修改已有类,实现对扩展是开发,对修改关闭。

相关推荐
ZHE|张恒1 小时前
Spring Bean 生命周期
java·spring
夏天的味道٥3 小时前
@JsonIgnore对Date类型不生效
开发语言·python
q***38513 小时前
SpringCloud实战十三:Gateway之 Spring Cloud Gateway 动态路由
java·spring cloud·gateway
小白学大数据4 小时前
Python爬虫伪装策略:如何模拟浏览器正常访问JSP站点
java·开发语言·爬虫·python
SEO_juper4 小时前
别再纠结LLMs.txt了!它背后的真相与最佳使用场景,一文讲透。
开发语言·ai·php·数字营销
程序员西西4 小时前
SpringBoot接口安全:APIKey保护指南
java·spring boot·计算机·程序员·编程·编程开发
g***B7385 小时前
JavaScript在Node.js中的模块系统
开发语言·javascript·node.js
summer_west_fish5 小时前
单体VS微服务:架构选择实战指南
java·微服务·架构
v***8575 小时前
Ubuntu介绍、与centos的区别、基于VMware安装Ubuntu Server 22.04、配置远程连接、安装jdk+Tomcat
java·ubuntu·centos
烤麻辣烫5 小时前
黑马程序员大事件后端概览(表现效果升级版)
java·开发语言·学习·spring·intellij-idea