设计模式面试题(二):设计模式之工厂模式

导读:本篇文章讲解 设计模式面试题(二):设计模式之工厂模式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

三、工厂模式

1、什么是工厂模式

它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。实现了创建者和调用者分离,工厂模式分为简单工厂、工厂方法、抽象工厂模式。

2、工厂模式好处

  • 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替 new 操作的种模式。
  • 利用工厂模式可以降低程序的耦合性,为后期的维护修改提供了很大的便利。
  • 将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。

3、为什么要学习工厂设计模式

不知道你们面试题问到过源码没有,你知道 Spring 的源码吗,MyBatis 的源码吗,等等等 如果你想学习很多框架的源码,或者你想自己开发自己的框架,就必须先掌握设计模式(工厂设计模式用的是非常非常广泛的)

4、Spring 开发中的工厂设计模式

4.1、Spring loC

  • 看过 Spring 源码就知道,在 Spring lOC容器创建 bean 的过程是使用了工厂设计模式。
  • Spring 中无论是通过xml配置还是通过配置类还是注解进行创建 bean,大部分都是通过简单工厂来进行创建的。
  • 当容器拿到了 beanName 和 class 类型后,动态的通过反射创建具体的某个对象,最后将创建的对象放到 Map 中。

4.2、为什么 Spring loC 要使用工厂设计模式创建 Bean 呢

  • 在实际开发中,如果我们 A 对象调用 B,B 调用 C,C 调用 D 的话我们程序的耦合性就会变高。 (耦合大致分为类与类之间的依赖,方法与方法之间的依赖。)
  • 在很久以前的三层架构编程时,都是控制层调用业务层,业务层调用数据访问层时,都是是直接 new 对象,耦合性大大提升,代码重复量很高,对象满天飞。
  • 为了避免这种情况,Spring 使用工厂模式编程,写一个工厂,由工厂创建 Bean,以后我们如果要对象就直接管工厂要就可以,剩下的事情不归我们管了。SpringlOC容器的工厂中有个静态的 Map 集合,是为了让工厂符合单例设计模式,即每个对象只生产一次,生产出对象后就存入到 Map 集合中,保证了实例不会重复影响程序效率。

5、工厂模式分类

工厂模式分为:简单工厂、工厂方法、抽象工厂模式

  • 简单工厂 : 用来生产同一等级结构中的任意产品。(不支持拓展增加产品)
  • 工厂方法 : 用来生产同一等级结构中的固定产品。(支持拓展增加产品)
  • 抽象工厂 :用来生产不同产品族的全部产品。(不支持拓展增加产品;支持增加产品族)

我下面来使用代码演示一下!

5.1、简单工厂模式

什么是简单工厂模式?

简单工厂模式相当于是一个工厂中有各种产品,创建在一个类中,客户无需知道具体产品的名称,只需要知道产品类所对应的参数即可。但是工厂的职责过重而且当类型过多时不利于系统的扩展维护。

代码演示:
创建工厂

package com.lijie;

public interface Car{
    public void run();
}

创建工厂的产品 (宝马)

package com.lijie;
public class Bmw implements Car{
    public void run(){
        System.out.println("我是宝马汽车...");
    }
}

创建工另外一种产品 (奥迪)

package com.lijie;

public class AoDi implements Car(){
    public void run(){
        System.out.println("我是奥迪汽车..");
    }
}

创建核心工厂类,由他决定具体调用哪产品
 

package com.lijie;

public class CarFactory{
    public static Car createCar(String name){
        if ("".equals(name)) {
            return null;
        }
    
        if(name.equals("奥迪")){
            return new AoDi();
        }

        if(name.equals("宝马")){
            return new Bmw();
        }
        return null;
    }
}

演示创建工厂的具体实例

package com.lijie;

public class Client01 {
    public static void main(String[] args) {
        Car aodi = CarFactory.createCar("奥迪");
        Car bmw = CarFactory.createCar("宝马");
        aodi.run();
        bmw.run();
    }
}

单工厂的优点/缺点

  • 优点: 简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
  • 缺点: 很明显工厂类集中了所有实例的创建逻辑,容易违反 GRASPR 的高内聚的责任分配原则。

5.2、 工厂方法模式

什么是工厂方法模式

工厂方法模式 Factory Method,又称多态性工厂模式。在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节

代码演示:

创建工厂

package com.lijie;

public interface Car{
    public void run();
}

创建工厂方法调用接口 (所有的产品需要 new 出来必须继承他来实现方法)
 

package com.lijie;

public interface CarFactory {
    Car createCar();
}

创建工厂的产品 (奥迪)

package com.lijie;

public class AoDi implements Car{
    public void run(){
        System.out.println("我是奥迪汽车..");
    }
}

创建工厂另外一种产品 (宝马)

package com.lijie;

public class Bmw implements Car{
    public void run(){
        System.out.println("我是宝马汽车...");
    }
}

创建工厂方法调用接口的实例 (奥迪)
 

package com.lijie;

public class AoDiFactory implements CarFactory{

    public Car createCar(){
        return new AoDi():
    }
}

创建工厂方法调用接口的实例 (宝马)

package com.lijie;

public class BmwFactory implements CarFactory{
    public Car createCar(){
        return new Bmw();
    }
}

演示创建工厂的具体实例

package com.lijie;
    public class Client{

    public static void main(String[] args){
        Car aodi = new AoDiFactory().createCar();
        Car jili = new BmwFactory().createCar();
        aodi.run();
        jili.run();
    }
}

5.3、抽象工厂模式

什么是抽象工厂模式

抽象工厂简单地说是工厂的工厂,抽象工厂可以创建具体工厂,由具体工厂来产生具体产品。

代码演示:

创建第一个子工厂,及实现类
 

package com.lijie;

//汽车
public interface Car{
    void run();
}

class CarA implements Car{
    public void run(){
        System.out.println("宝马");
    }
}

class CarB implements Car{
    public void run(){
        System.out.println("摩拜");
    }
}

创建第二个子工厂,及实现类
 

package com.lijie;

//发动机
public interface Engine{
    void run();
}

class EngineA implements Engine{
    public void run(){
        System.out.println("转的快!");
    }
}

class EngineB implements Engine{
    public void run();
        System.out.println("转的慢!");
    }
}

创建一个总工厂,及实现类 (由总工厂的实现类决定调用那个工厂的那个实例)
 

package com.lijie;

public interface TotalFactory{
    // 创建汽车
    Car createChair();
    // 创建发动机
    Engine createEngine();
}

//总工厂实现类,由他决定调用哪个工厂的那个实例
class TotalFactoryReally implements TotalFactory{
    public Engine createEngine(){
        return new EngineA();
    }

    public Car createChair(){
        return new CarA();
    }
}

运行测试

package com.lijie;

public class Test{

    public static void main(String[] args){
        TotalFactory totalFactory2 = new TotalFactoryReally();
        Car car = totalFactory2.createChair();
        car.run();

    TotalFactory totalFactory = new TotalFactoryReally();
    Engine engine = totalFactory.createEngine();
    engine.run();
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/111804.html

(0)
Java光头强的头像Java光头强

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!