设计模式太难学?JAVA设计模式之工厂方法模式

设计模式太难学?JAVA设计模式之工厂方法模式,第1张

设计模式太难学?

简单工厂模式


文章目录
  • 设计模式太难学?
  • 前言
  • 一、工厂方法模式
  • 二、简单工厂和工厂方法之间的区别
    • 简单工厂模式
    • 工厂方法模式
  • 总结
    • 简单工厂模式:
    • 工厂方法模式:


前言

之前学习了简单工厂模式,发现如果工厂要新增生产对象的话,就得修改工厂类,但这样就违背了开闭原则。为了解决这一问题,便衍生了下面这一个工厂方法模式。


一、工厂方法模式

先思考一个问题。当你的类、方法写的很复杂很不好扩展的时候应该如何解决?
答:抽它!把一些可能公共的逻辑抽象起来。


这里是一样的道理,工厂方法模式在简单工厂模式的基础上,将工厂类进行抽象,根据依赖倒置的原则,客户端(调用方)只需要跟抽象的工程接口打交道,运行时再根据真正需调用的实现传入并完成调用

二、简单工厂和工厂方法之间的区别

上面单纯的文字说明工厂方法模式有点模糊,下面直接放代码来解释

简单工厂模式

先创建客户端类、产品抽象接口、具体产品实现类、工厂类 这四个角色的类或接口:

产品相关

//产品抽象接口
public interface Product {

     void make();
}

//产品实现类-phone
public class Phone implements Product{
    @Override
    public void make() {
        System.out.println("生产一部手机");
    }
}

//产品实现类-computer
public class Computer implements Product{
    @Override
    public void make() {
        System.out.println("生产了一台电脑");
    }
}

工厂类

public class ProductFactory {

    public static Product createProduct(String product){
        if ("phone".equals(product)){
            return new Phone();
        }
        if ("computer".equals(product)){
            return new Computer();
        }
        return null;
    }
}

客户端类

public class Client {

    public static void main(String[] args) {
        //通过工厂类创建“phone”产品
        Product phone = ProductFactory.createProduct("phone");
        phone.make();
        //通过工厂类创建“computer”产品
        Product computer = ProductFactory.createProduct("computer");
        computer.make();
    }
}

运行结果

上面就是一个简单工厂模式的demo。客户端类通过传入不同的参数调用工厂类的方法,从而得出不同的产品对象。
目前工厂类ProductFactory里只生产两种产品:phone和computer。如果我后期想新增一个watch的产品,就得修改工厂类,去实现watch逻辑的添加

 public static Product createProduct(String product){
        if ("phone".equals(product)){
            return new Phone();
        }
        if ("computer".equals(product)){
            return new Computer();
        }
        //新增
        if ("watch".equals(product)){
            return new Watch();
        }
        return null;
    }

这样因为加一个产品而去修改工厂类,其实不符合设计模式的开闭原则:对新增开放,对修改关闭。

工厂方法模式

看下工厂方法模式是怎样的。它有以下几个角色:客户端类、产品抽象接口、产品实现类、工厂抽象接口、工厂实现类
工厂方法模式较之简单工厂模式的区别就在于对工厂的抽象。

产品相关

//产品抽象接口
public interface Product {

     void make();
}

//产品实现类-phone
public class Phone implements Product{
    @Override
    public void make() {
        System.out.println("生产一部手机");
    }
}

//产品实现类-computer
public class Computer implements Product{
    @Override
    public void make() {
        System.out.println("生产了一台电脑");
    }
}

工厂相关

//抽象出来的工厂接口
public interface AbstractFactory {

    Product createProduct();
}

//创建phone产品的工厂类
public class PhoneFactory implements AbstractFactory{
    @Override
    public Product createProduct() {
        return new Phone();
    }
}

//创建computer产品的工厂类
public class ComputerFactory implements AbstractFactory{
    @Override
    public Product createProduct() {
        return new Computer();
    }
}

客户端类

public class Client {

    public static void main(String[] args) {
        //拿到工厂类(真正开发中,为了符合开闭原则,客户端类一般都是通过反射方式创建工厂对象,通过配置文件配置某一工厂实现类标识,代码运行时去读取配置,通过反射生成AbstractFactory,再完成调用)
        AbstractFactory phoneFactory = new PhoneFactory();
        //创建产品
        phoneFactory.createProduct().make();

        AbstractFactory computerFactory = new ComputerFactory();
        //创建产品
        computerFactory.createProduct().make();

    }
}

说明一下:真正开发中,为了符合开闭原则,客户端类一般都是通过反射方式创建工厂对象,通过配置文件配置某一工厂实现类标识,代码运行时去读取配置,通过反射生成AbstractFactory,再完成调用

运行结果

跟简单工厂模式达到了同样的运行效果,现在假如说需要添加一个watch的产品。只需要实现一个WatchFactory实现AbstractFactory抽象工厂即可。

新增watch产品改造

//新增watch产品类
public class WatchProduct implements Product{
    @Override
    public void make() {
        System.out.println("生产了一条手表");
    }
}

//新增watch产品工厂类,实现AbstractFactory接口
public class WatchFactory implements AbstractFactory{
    @Override
    public Product createProduct() {
        return new WatchProduct();
    }
}

//客户端调用
public class Client {

    public static void main(String[] args) {
        //拿到工厂类(真正开发中,为了符合开闭原则,客户端类一般都是通过反射方式创建工厂对象,通过配置文件配置某一工厂实现类标识,代码运行时去读取配置,通过反射生成AbstractFactory,再完成调用)
        AbstractFactory phoneFactory = new PhoneFactory();
        //创建产品
        phoneFactory.createProduct().make();

        AbstractFactory computerFactory = new ComputerFactory();
        //创建产品
        computerFactory.createProduct().make();
        
        AbstractFactory watchFactory = new WatchFactory();
        //创建产品
        watchFactory.createProduct().make();
    }
}

运行效果

可以看到,在我们客户端需要新增wtach产品创建时,只是新增了对应的产品类和产品工厂类。并未修改之前的任何代码。这样就做到了良好的可扩展性,在不修改已有代码的基础上新增新的功能代码。工厂方法模式就很符合开闭原则。

总结 简单工厂模式:

工厂和产品是1对多的关系,一个工厂类创建多个产品。需新增产品时则需修改工厂类

虽然帮我们解耦,把对象的创建和使用分离开来。但是由于其不符合开闭原则,不方便扩展。所以可用性极差。不推荐使用。

简单总结:有解耦的特点(所有工厂模式都有的特点)但不符合设计模式的开闭原则,不建议使用

工厂方法模式:

工厂和产品是1对1的关系,一个工厂类创建一个产品,符合单一原则。且在需要新增产品时,则新增其对应的产品工厂类即可。不修改原有代码,符合开闭原则。

工厂方法模式是目前工厂模式中运用最广泛的一种,但工厂方法模式也有其一定的缺点,由于一个产品对应一个工厂类,如果产品种类多的时候,对应的产品工厂类也会增多。这样就加大了系统的开销,因为jvm需要编译加载这些工厂类。

简单总结:符合设计模式单一原则、开闭原则。目前大多流行使用。但容易造成类的个数增加,会造成一定的系统额外开销(适用于被创建的产品种类不多的情况)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/732847.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-27
下一篇 2022-04-27

发表评论

登录后才能评论

评论列表(0条)

保存