面试题:设计模式——工厂模式

本文详细介绍了工厂模式的概念及其三种主要类型:简单工厂模式、工厂方法模式和抽象工厂模式。通过具体的代码示例,展示了如何使用这些模式来降低软件系统的耦合度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工厂模式是现实生活中常见的场景,在面向对象编程中,也是我们经常使用的,也许我们早已经接触了,只是不知道原来这也是一种设计模式,俗话说,越是平常的就越容易忽略,但是不能忽视他的作用,存在价值。

一.概述
工厂模式:顾名思义,就是生产产品,因此属于创建型设计模式,需要生成的对象就是产品,生成对象的地方叫做工厂。工厂模式实现了创建者和调用者的分离。

二.特点
定义一个用于创建的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延伸到其子类。降低耦合度
简单的说,工厂模式的核心本质就是实例化对象,用工厂方法代替new操作,将选择实现类,创建对象统一管理和控制,从而将调用者跟我们的实现类解耦。

三.分类
1.简单工厂模式(静态工厂)
2.工厂方法模式
3.抽象工厂模式

1.简单工厂模式(静态工厂)
如果你要建一个工厂,首先要确定你这个工厂究竟要生产什么产品,假如是生产手机,那先确定好方向(建一个抽象类或者接口)

public abstract class Phone {
//具体的手机型号,由子类实现
    public Phone() {
    }

}

知道要生产的是手机之后,还要确定生产的手机型号

public class Phone1 extends Phone {
    public Phone1(){
        System.out.println("生产Phone1");
    }

}
public class Phone2 extends Phone {
    public Phone2() {
        System.out.println("生产Phone2");
    }


现在有想生产的产品了,但是需要生产产品的地方,因此就要建立一个工厂。

public class SimpleFactory {
    /**
     * 简单工厂:这是一个具体的类,不是接口,也不是抽象类
     * 工厂应该有一个创建方法,并且是静态的,因此也称为静态工厂
     */
    public static final int TYPE_P1 = 1;//phone1
    public static final int TYPE_P2 = 2;//pone2

    public static Phone createPhone(int type) {
        switch (type) {
            case TYPE_P1:
                return new Phone1();
            case TYPE_P2:
                return new Phone2();
            default:
                return new Phone1();//默认制造的是phone1
        }
    }
}

有产品,也有工厂了,那如果我们需要这个产品的话,就去工厂指定产品。

public class Customer {
    public static void main(String [] args){
        //需要一台Phone1
        SimpleFactory simpleFactory=new SimpleFactory();
        Phone phone1=simpleFactory.createPhone(SimpleFactory.TYPE_P1);

    }
}

输出:

生产Phone1

到这里我们会觉得上面的代码十分熟悉,就是经常都在使用的,特点是在面向对象的多态这一点上。但是你有没有想过这样的一种情况呢?增加一个产品phone3,除了要增加一个具体的phone3产品类,还需要去修改简单工厂类的方法(新增case);而这样一来,简单工厂和每一个具体产品是联系比较密切,牵一发而动全身,这显然是不符合低耦合的,而且不同的产品需要不同额外参数的时候不支持。因此我们有另外一种简单工厂来解决**不用修改create()**代码。
2.简单工厂(反射)

public class SimpleFactory1 {
    public static  <T extends Phone> T createProduct(Class<T> c){
        Phone phone=null;
        try {
            phone = (Phone) Class.forName(c.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            //异常处理
        }
        return (T)phone;
    }
}

顾客类:

public class Customer {
    public static void main(String [] args){
        //需要一台Phone1
        SimpleFactory simpleFactory=new SimpleFactory();
        Phone phone1=simpleFactory.createPhone(SimpleFactory.TYPE_P1);
       //需要一台Phone2,利用反射
        System.out.println("利用反射机制:");
        Phone phone2 = SimpleFactory1.createProduct(Phone2.class);

    }

输出:

生产Phone1
利用反射机制:
生产Phone2

当你终于把反射的简单工厂看完之后,再细想一下,你会觉得欲哭无泪,因为这个和new Object()是一样的性质,当需要调用有参的构造函数时便无能为力了,这样像为了工厂而工厂。同样解决不了不同的产品需要不同额外参数的时候 不支持这个问题…看到这里是不是要崩溃了,先稳住!相信了解了工厂方法模式会赢的!
3.工厂方法模式
还记得最开始写的特点里面有这样一句话吗?——工厂方法使一个类的实例化延伸到其子类。这句话其实就是把简单工厂中具体的工厂类,划分为两层:抽象工厂+具体的工厂子类
首先:创建抽象工厂,接口也可以

interface PhoneFactory {
    Phone create();
}

子类:

public class FactoryPhone1 implements PhoneFactory {
    @Override
    public Phone1 create() {
        return new Phone1();
    }
}
public class FactoryPhone2 implements PhoneFactory {
    @Override
    public Phone2 create() {
        return new Phone2();
    }
}

客户类:

 //工厂方法
        FactoryPhone1  factoryPhone1 = new FactoryPhone1();
        Phone phone1 = factoryPhone1.create();

输出:

生产Phone1

看了这个之后是不是觉得这种更面向对象呢?并且当需求变化,只需要增删相应的类,不需要修改已有的类。更符合开闭原则。但是工厂方法模式也有弊端:对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。所以也有另外一种多方法工厂
4.多方法工厂
模仿Executors类。

public class MulMayFactory {
    //提供共有的静态工厂方法
    public static Phone createPhone1() {
        return new Phone1();
    }

    public static Phone createPhone2() {
        return new Phone2();
    }
}

顾客类:

Phone phone1=MulMayFactory.createPhone1();

用静态工厂方法代替构造器的方法的优势:
1.有名称(客户端代码更易于阅读)
2.不必在每次调用它们的时候都创建一个新的对象。
3.可以返回原返回类型的任何子类型的对象
4.在创建参数化类型实例的时候,它们使代码变得更加简单


以上就是简单工厂模式,工厂方法模式,抽象工厂模式会在后面陆续学习。
学习参考:
https://blog.youkuaiyun.com/jason0539/article/details/23020989
https://blog.youkuaiyun.com/zxt0601/article/details/52798423
《Effective Java中文版第二版第二章第一条》

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值