• 设计模式简单工厂


    简单工厂(factory)模式:是个人都会的设计模式

     相关面试说明:

    平时面试的一个段子:一般面试时,设计模式是必问的,因为这个东西很重要,设计模式掌握的好不好,决定了会不会写出屎一样的代码。最讨厌的其实就是,在自己的team里面,有同学在这个复杂的系统里面,去制造出来屎一样的代码,然后就导致,这个同学如果一旦离职了以后,后面整个系统很难 维护、扩展、升级,修复bug。

    但是从大量的面试中,可以分享一个结论,就是基本上 你面100个人,90个人,差不多就是90%这个比例,然后会告诉你,他说,我就会这个 工厂模式 和 单例模式,呵,真实一个笑话啊,身为一个工作几年的程序员来说,就会 工厂模式 和 单例模式,但是这个东西,基本上也验证了说,为什么 简单工厂模式是 是个人都会的设计模式,因为基本上 我就从来没有遇到过一个人说,连工厂模式都不会用的啊。

    那这个模式因为它太简单了,所以就快速的来说一下。

    不用简单工厂模式的代码实现: 

    假设说,我们现在需要,生产出来了一个对象Product,然后我们如果不用模式的话,是怎么来做。。。

    首先,创建一个类,叫WithoutFactoryPatternDemo,其中,

    比如说,我们这边来定义一个静态类Product,我们要创建出来这么一个产品Product;

    然后 private String name;,其中有一个属性name;

    然后 添加构造函数,get/set/toString方法,再写一个main方法;

    现在假设说,我们就要创建Product这样一个对象,要怎么来做;

    main方法中 Product product = new Product("测试产品");,然后 执行输出一下 System.out.println("product");,输出结果为 Product [name=测试产品]。

     代码如下:

    public class WithoutFactoryPatternDemo {
    
        public static void main(String[] args) {
            Product product = new Product("测试产品");
            System.out.println(product);
    
        }
    
        public static class Product {
    
            private String name;
    
            public Product(String name) {
                super();
                this.name = name;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            @Override
            public String toString() {
                return "Product{" +
                        "name='" + name + '\'' +
                        '}';
            }
        }
    }

    不用简单工厂模式的问题所在:

    那这段代码有什么问题,ok,很简单。如果你直接面向一个类来编程,直接通过new来创建类的实例的话,你基本上就是,后面会死的很惨啊。

    假设,我们如果对这个Product,要更换一个类,就是换一个类的实现,此时就必须在,创建这个实例 和 所有调用这个类实例 的地方,都要修改一下这个代码,什么意思。

    我现在把这个Product,给它改成,叫做Product2,然后构造方法也要随着改成Product2。

    public class WithoutFactoryPatternDemo {
    
        public static void main(String[] args) {
            Product2 product = new Product2("测试产品");
            System.out.println(product);
    
        }
    
        public static class Product2 {
    
            private String name;
    
            public Product2(String name) {
                super();
                this.name = name;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            @Override
            public String toString() {
                return "Product{" +
                        "name='" + name + '\'' +
                        '}';
            }
        }
    }

    然后你看,你一改这个类名Product为Product2,main方法中调用Product的逻辑就报错了,就要改成Product2 product = new Product2("测试产品");,

    那这样好么,如果你有100个地方都,创建了Product这个类的实例,你需要在100个地方啊,都去修改这个new Product()的这段代码,这个代码可维护性,和可扩展性之差,惨目忍睹,垃圾代码,这就是垃圾代码。

    应用简单工厂模式的代码实现:

    那么,为了去避免这个问题,最简单的方式,应该怎么去做,就是用这个FactoryPatternDemo,简单工厂模式。

    首先,我们先来定义一个接口,Product,接口中定义一个方法void execute();。

    然后的话呢,这边的话是,然后我们是定义一个静态的Product接口的实现类,public static class ProductImpl1 implement Product{... },

    在execute方法实现中输出一句话,产品1的功能实现。System.out.println("产品1的功能实现");,

    然后我们再定义一个工厂ProductFactory,public static class ProductFactory{...},

    里面有一个静态方法create(),public static Product create(){ return new ProductImpl1();},方法里面返回ProductImpl1的实现。

    然后这个main方法里面,这时 如果再要创建Product这个对象怎么创建,Product product = ProductFactory.create();,然后product.execute();,

    我们输出来看一下,ok,产品1的功能实现。

    public class FactoryPatternDemo {
    
        public static void main(String[] args) {
            Product product = ProductFactory.create();
            product.execute();
        }
        public interface Product{
            void execute();
        }
    
        public static class ProductImpl1 implements Product {
    
            @Override
            public void execute() {
                System.out.println("产品1的功能实现");
            }
        }
    
        public static class ProductFactory {
    
            public static Product create(){
                return new ProductImpl1();
            }
        }
    }

    使用工厂模式的好处:

    好,我们这个,它的整个核心思路是什么,就是绝对不在任何一个,就是要使用Product这个类的地方,然后手动去new一个类出来,而是把new这个类的这个操作,转移到一个工厂里面去,然后你找这个工厂的一个静态方法,这个工厂的静态方法里面就给你创建一个对象,给你返回回来,也就是说,选择说创建哪个类的实例的这个过程(比如ProductImpl1),放在这个工厂里面了,然后我们面向这个,要使用这个对象的接口Product,面向接口去编程。这个Product是个接口对吧.

    好,这个时候假设说,我把这个ProductImpl1,给它改成ProductImpl2,那么只要在这(ProductFactory)工厂的静态方法中改一下,把返回new的ProductImpl1的实例,改为返回new的ProductImpl2的实例,就可以。然后main方法中调用Product的代码,变都不用变,连动都不用动,这就是面向接口编程,然后从工厂里面拿对象实例的这个好处,这就是所谓的工厂模式啊。那么,如果此时有100个地方啊,都需要获取这个,Product这个实例,对吧,但是此时这个Product的实现类 改了,我们只要修改一个地方即可。就是那个ProductFactory中,ok,这个就是它的一个好处。

    工厂模式最常见的实际应用场景:

    工厂模式,这个实在是太简单了,所以说,在真正企业的这个实际运用中,其实工厂模式,真正真正,就是最最常见的实践就是Spring啊。因为Spring容器就是一个大工厂,一个概念,就是Spring会基于这个xml,或者是这个注解,就是根据一些配置,然后去创建出来所有我们需要的类的实例,就比如说,我们现在搞了一个

    @Service

    public class UserServiceImpl implement UserService{}

    这个东西,那么这个时候,其实Spring看到这个@Service注解,它就会去创建 一个UserServiceImpl它的这个实例出来,然后把它放到,Spring自己内部的这个容器里面,这个,此时Spring就相当于是个工厂,它里面什么实例都有,然后,我们如果要使用UserService的地方,比如说咱们写了一个

    public class UserController{

      @Autowired

      private UserService userService;

    }

    这个里面怎么去使用,直接,就是可能@Autowired,然后private UserService userService,面向接口,面向UserService这个接口编程,然后Spring这个工厂会扫描到这个注解@Autowired,会自动把UserServiceImpl这个类的实例给注入进来,把这个实例注入给这个UserService接口在UserController这里用。

    ok,那么通过这样的方式,UserController这块,是不care说,它这个UserService的接口实现类是谁的,一旦说我们要把这个UserServiceImpl给它改了UserServiceImpl2,ok,没问题啊,这个UserController这个类,完全不用做任何的这个修改,那么Spring会找到UserServiceImpl2这个类,去初始化UserServiceImpl2的这个类的实例,然后,把这个类的实例,给注入到UserController调用者这里来。

    所以说,Spring本身就是一个工厂模式,最好最好的一个体现啊。也就是说我们那个,在项目中大量的用SpringIOC这块功能,其实本身就是在实践工厂模式,但是,如果我们自己要实现,我们自己如果要去这个工厂的话,其实也是有这种场景的。在后续的电商项目里面,我们会把工厂模式,跟构造器模式结合起来,还有一些别的模式,会结合具体的业务去演示,怎么自己去做工厂模式实现,怎么去做。

    ok,也就是说这个模式,首先,你用Spring就是在实践,另外,我们为了自己手动实现去体验,我们会结合电商的业务演示怎么去用。

  • 相关阅读:
    js浏览器之浏览器对象
    js浏览器
    js面向对象编程之创建对象
    js面向对象编程
    STS清理
    使用STS新的工作空间无需再配置
    去掉文本框中的空格
    MySQL轻量版使用,无需安装,无脑操作
    Eclipse&STS常用小技巧
    如何配置上传虚拟路径问题?
  • 原文地址:https://www.cnblogs.com/HarryVan/p/16422816.html
Copyright © 2020-2023  润新知