栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式学习---Java工厂模式(Factory)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式学习---Java工厂模式(Factory)

普通工厂模式

概念

普通工厂方法模式就是建立一个工厂类,对实现了同一接口的不同实现类进行实例的创建。实际上就是new对象

类图

右侧一个接口(Sender)两个实现类(MailSender、SmsSender),左侧工厂类(SendFactory)produce方法有一个String类型的参数type,返回值为Sender(构成多态)。代码如下:
Sender

public interface Sender {
    // 自定义抽象方法
    void send();
}

MailSender

public class MailSender implements Sender {
    @Override
    public void send() {
        System.out.println("正在发送邮件!!");
    }
}

SmsSender

public class SmsSender implements Sender {
    @Override
    public void send() {
        System.out.println("正在发送短信!!");
    }
}

SendFactory

public class SendFactory {
    // 自定义成员方法实现对象的创建
    public Sender produce(String type){
        if("mail".equals(type)){
            return new MailSender();
        }
        if("sms".equals(type)){
            return new SmsSender();
        }
        return null;
    }
}

测试类SendFactoryTest 及优缺点说明

public class SendFactoryTest {
    public static void main(String[] args) {
        // 优点:扩展性和可维护性更强! 尤其是在创建大量对象的前提下
        // 缺点:代码略复杂,可读性略差
        // 最主要的缺点在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,并且可能出现空指针异常。
        
        // 1.声明工厂类类型的引用指工厂类类型的对象
        SendFactory sf = new SendFactory();
        // 2.调用生产方法来实现对象的创建
        Sender sender = sf.produce("mail");
        // 3.使用对调用方法模拟发生的行为
        sender.send();

        System.out.println("-----------------------------------------");
        
    }
}

运行结果:

对普通工厂类可能出现空指针异常的缺点,我们做出了一个改进:多个工厂方法模式

多个工厂方法模式

多个工厂模式与普通工厂模式在类图上可以看出,主要的不同就是普通工厂模式是一个方法创建多个对象,多个工厂模式变成了 两个方法各自创建自己的对象。

public class SendFactory {
    // 缺点:在多个工厂方法模式中,为了能够正确创建对象,先需要创建工厂类的对象才能调用工厂类中的生产方法。
    // 就是说需要在main()方法里面创建SendFactory这个类型的对象,才可以调用
    public Sender produceSms(){
        return new SmsSender();
    }
    public Sender produceMail(){
        return new MailSender();
    }
}

这样,就可以解决因为传字符串参数出错导致的空指针问题了。但是还是有一些问题,我们继续优化。
在代码块中我们已经提到了该方法的缺点,就是在调用方法的时候我们还需要先new()一个工厂类的对象才可以调用它的方法,解决办法当然有,而且还很简单。我们只需要把方法提升到类层级,使方法可以通过 类名. 的方式调用就可以了,也就是说,给每一个方法加上static关键字修饰,变成:静态工厂方法模式

静态工厂方法模式


SendFactory

public class SendFactory {
    public static Sender produceSms(){
        return new SmsSender();
    }
    public static Sender produceMail(){
        return new MailSender();
    }
}

SendFactoryTest

public class SendFactoryTest {
    public static void main(String[] args) {
        SendFactory.produceMail();
        SendFactory.produceSms();
 	}
}

至此,我们已经得到了很优秀的工厂方法模式的代码。
工厂方法模式的实际意义
工厂方法模式适合:凡是出现了大量的产品(对象)需要创建,且拥有共同的接口的时候,可以通过工厂方法模式进行创建。
工厂方法模式的主要缺点
类的创建依赖于工厂类,也就是说,如果需要拓展新的业务,生产新的产品,就必须去修改工厂的类代码。我们学习设计模式的时候讲到过,要遵循的开闭原则,在这里并没有实现。所以还存在一定的问题,并没有做到对修改关闭。这里我们提出了另一个模式。。。

抽象工厂模式


从类图中不难看出抽象工厂模式与之前的工厂模式的区别,我们直接来看代码:
Provider

public interface Provider {
    // 自定义抽象方法描述产品的生产
    Sender produce();
}

MailSendFactory

public class MailSendFactory implements Provider {
    @Override
    public Sender produce() {
        return new MailSender();
    }
}

SmsSendFactory

public class SmsSendFactory implements Provider {
    @Override
    public Sender produce() {
        return new SmsSender();
    }
}

SendFactoryTest

public class SendFactoryTest {
    public static void main(String[] args) {
        Provider provider = new MailSendFactory();
        Sender sender1 = provider.produce();
        sender1.send();
        provider = new SmsSendFactory();
        Sender sender2 = provider.produce();
        sender2.send();
    }
}

结果:

优点说明:
我们说抽象工厂模式解决了上面几个工厂模式没有实现的开闭原则,如果需要拓展新的业务,生产新的产品,使用抽象工厂模式就只需要增加一个类并且让这个类实现Provider这个接口就可以了,又得到了扩展,有没有修改原有的代码,对工厂模式来说简直完美!

到此,工厂模式学习完毕。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/356334.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号