设计模式之工厂模式

Spring中的各大模块使用的设计模式:

Spring IOC 工厂,单例,装饰器

Spring AOP 代理,观察者

 Spring MVC 委派,适配器

Spring JDBC 模板方法 

工厂模式相关介绍:

工厂模式的概念:

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

意图:

定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

主要解决:主要解决接口选择的问题。

何时使用:我们明确地计划不同条件下创建不同实例时。

如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。

关键代码:创建过程在其子类执行。

应用实例: 

1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。

2、Hibernate 换数据库只需换方言和驱动就可以。

优点:

 1、一个调用者想创建一个对象,只要知道其名称就可以了。

2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。

3、屏蔽产品的具体实现,调用者只关心产品的接口。

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

使用场景: 

1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。

2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。

3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。

注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

三种工厂模式介绍以及实现:

第一种简单工厂模式(Simple Factory Pattern)

是指由一个工厂对象决定创建出那种产品的实例。它属于创建型模式,但它不属于GOF,23中设计模式。

下面通过三种方式,逐层深入的方式带你了解简单工厂模式。

案例背景:开设的培训班,有java,有Python,大数据,人工智能等课程。

方式一:通过传不同课程参数创建课程类,并调用对应的方法。

首先先创建一个课程接口ICourse,后面再创建一个java实现,大数据实现。

/**
 * Created by lijianfang on 2021/9/19.
 */
public interface ICourse {

public void record();
}


在分别创建java课程,大数据课程,python课程等

/**
 * Created by lijianfang on 2021/9/19.
 */
public class BigDataCourse implements ICourse {
    public void record() {
        System.out.printf("正在学习大数据课程");
    }
}
/**
 * Created by lijianfang on 2021/9/19.
 */
public class JavaICourse implements ICourse{

    public void record() {
        System.out.println("正在学习java课程");
    }
}

创建工厂类,使用参数进行创建。传不同的参数创建不同的课程。 

package com.packer.partten.factory;

/**
 * Created by lijianfang on 2021/9/20.
 */
public class CourseFactory {
     /**
     * <p>
     *  创建工厂方式一
     * </p>
     * @param courseName
     * @return
     */
    public ICourse createCourseOne(String courseName){
        if("java".equals(courseName)){
            return new JavaICourse();
        }else if("python".equals(courseName)){
            return new PythonCourse();
        }else {
            return null;
        }
    }
}

后面创建测试类,直接在主方法中传参数

/**
 * Created by lijianfang on 2021/9/19.
 */
public class SimlpleFactoryTest {
    public static void main(String[] args) {
        CourseFactory factory = new CourseFactory();
        ICourse javaCourse = factory.createCourseOne("java");
        javaCourse.record();
        
    }
}

测试结果:

正在学习java课程
Process finished with exit code 0

方式二:通过类的包名来创建对应的课程类,并调用方法。

工厂CourseFactory.java 类中添加如下方法:

    /**
     * 通过路径名创建
     * @param className
     * @return
     */
    public ICourse createCourseTwo(String className){
       try{
           if(!(null==className||"".equals(className))){
               return (ICourse) Class.forName(className).newInstance();
           }
       }catch (Exception e){
           System.out.println("className = [" + className + "]");
       }
       return null;
    }

测试类中如下调用SimlpleFactoryTest.java中如下调用:

       ICourse aCourse = factory.createCourseTwo("com.packer.partten.factory.PythonCourse");
        aCourse.record();

测试结果如下:

正在学习python课程

Process finished with exit code 0

方式三:通过类名创建对应的课程类,并调用方法。

工厂CourseFactory.java 类中添加如下方法:

    /**
     * 通过类创建
     * @param clzss
     * @return
     */
    public ICourse createCourseThree(Class clzss){
        try{
            if(null!=clzss){
                return (ICourse) clzss.newInstance();
            }
        }catch (Exception e){
            System.out.println("clzss = [" + clzss + "]");
        }
        return null;
    }

 测试类中如下调用SimlpleFactoryTest.java中如下调用:

        ICourse bCourse = factory.createCourseThree(BigDataCourse.class);
        bCourse.record();

测试结果如下:

正在学习大数据课程

Process finished with exit code 0

简单工厂模式的适用场景:

1.工厂类负责创建的对象比较少。

2.客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。

3.工厂类的职责相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背了开闭原则

4.不易于扩展过于复杂的产品解构

第二种工厂方法模式(Factory Method Pattern)

是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。属于创建型设计模式。

接下来通过代码进行实例演示:

创建课程工厂类

package com.packer.partten.factory.factorymethod;

import com.packer.partten.factory.simplefactory.ICourse;

/**
 * Created by lijianfang on 2021/9/20.
 */
public interface ICourseFactory {
    public ICourse create();
}

 创建java课程工厂

package com.packer.partten.factory.factorymethod;

import com.packer.partten.factory.simplefactory.ICourse;
import com.packer.partten.factory.simplefactory.JavaICourse;

/**
 * Created by lijianfang on 2021/9/20.
 */
public class JavaCourseFactory implements ICourseFactory{
    public ICourse create() {
        return new JavaICourse();
    }
}

创建python课程工厂

package com.packer.partten.factory.factorymethod;

import com.packer.partten.factory.simplefactory.ICourse;
import com.packer.partten.factory.simplefactory.PythonCourse;

/**
 * Created by lijianfang on 2021/9/20.
 */
public class PythonCourseFactory implements ICourseFactory {
    public ICourse create() {
        return new PythonCourse();
    }
}

创建工厂方法测试类

package com.packer.partten.factory.factorymethod;

import com.packer.partten.factory.simplefactory.ICourse;

/**
 * Created by lijianfang on 2021/9/20.
 */
public class MethodFactoryTest {
    public static void main(String[] args) {
        ICourseFactory factory = new PythonCourseFactory();
        ICourse pythonCourse = factory.create();
        pythonCourse.record();
    }
}

测试结果如下:

正在学习python课程
Process finished with exit code 0

适用场景:

1.创建对象需要大量重复代码。

2.客户端(应用层)不依赖于产品类实例如何被创建,实现等细节。

3.一个类通过其子类来指定创建那个对象。

优点:

1.用户只需要关心所需产品对应的工厂,无需关心创建细节。

2.加入新产品符合开闭原则,提高了系统的可扩展性。

缺点:

1.类的个数容易过多,增加了代码解构的复杂度

2.增加了系统的抽象性和理解难度。

第三种抽象工厂模式(Abstract Factory Pattern)

是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类。属于创建型设计模式。

同一个课程中有笔记,有视频录播,有直播。同一接口中必须实现三种。代码具体如下

创建ICourseFactory.java 工厂接口,包含录播课程,笔记,视频直播以公共的接口方式提给使用方。

package com.packer.partten.factory.abstactfactory;

import com.packer.partten.factory.simplefactory.ICourse;

/**
 * Created by lijianfang on 2021/9/20.
 */
public interface ICourseFactory {

    ICourse createCourse();

    INote createNote();

    IVideo createVideo();
}

创建单个java课程工厂javaCourseFactory.java

package com.packer.partten.factory.abstactfactory;

import com.packer.partten.factory.simplefactory.ICourse;
import com.packer.partten.factory.simplefactory.JavaICourse;

/**
 * Created by lijianfang on 2021/9/20.
 */
public class JavaCourseFactory implements ICourseFactory{

    public ICourse createCourse() {
        return new JavaICourse();
    }

    public INote createNote() {
        return  new JavaINote();
    }

    public IVideo createVideo() {
        return new JavaVideo();
    }
}

创建笔记课程类以及相应的接口

package com.packer.partten.factory.abstactfactory;

/**
 * Created by lijianfang on 2021/9/20.
 */
public interface INote {
    public void note();
}


package com.packer.partten.factory.abstactfactory;

/**
 * Created by lijianfang on 2021/9/19.
 */
public class JavaINote implements INote {

    public void note() {
        System.out.println("正在进行java笔记");
    }
}

创建视频录播课程类以及相应的接口

package com.packer.partten.factory.abstactfactory;

/**
 * Created by lijianfang on 2021/9/20.
 */
public interface IVideo {
    public void video();
}

package com.packer.partten.factory.abstactfactory;

/**
 * Created by lijianfang on 2021/9/20.
 */
public class JavaVideo implements IVideo{
    public void video() {
        System.out.println("正在进行视频直播课程");
    }
}

创建测试类AbstactFactoryTest.java

package com.packer.partten.factory.abstactfactory;

/**
 * Created by lijianfang on 2021/9/20.
 */
public class AbstactFactoryTest {
    public static void main(String[] args) {
        ICourseFactory factory = new JavaCourseFactory();
        factory.createCourse().record();
        factory.createNote().note();
        factory.createVideo().video();
    }
}

测试结果如下:

正在学习java课程
正在进行java笔记
正在进行视频直播课程

Process finished with exit code 0

使用场景:

1.客户端(应用层)不依赖于产品类实例如何被创建,实现等细节。

2.强调一系列相关的产品对象(同一产品族)一起使用创建对象需要大量重复的代码

3.提供一个产品类的库,所有的产品以同样的接口出现,从而是客户端不依赖于具体实现

优点:

1.具体产品在应用层代码隔离,无须关心创建细节

2.将一个系列的产品族统一到一起创建

缺点:

 1.规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口

2.增加了系统的抽象性和理解难度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
工厂模式是一种常见的创建型设计模式,用于创建对象,而不是通过直接调用构造函数来创建它们。工厂模式定义了一个接口,用于创建相关对象,但是让子类决定要实例化的类。在C++工厂模式可以通过以下步骤实现: 1. 创建一个抽象基类,该类定义了一个纯虚拟函数,该函数将返回一个指向基类的指针。这个基类就是我们的工厂接口。 ```c++ class Product { public: virtual ~Product() {} virtual void operation() = 0; }; ``` 2. 创建具体的产品类,它们继承自抽象基类,并实现了其纯虚拟函数。这些类就是我们的具体产品。 ```c++ class ConcreteProductA : public Product { public: void operation() override { /* 具体产品 A 的操作 */ } }; class ConcreteProductB : public Product { public: void operation() override { /* 具体产品 B 的操作 */ } }; ``` 3. 创建一个工厂类,该类实现了工厂接口,并根据需要创建具体的产品。这个工厂类就是我们的具体工厂。 ```c++ class Factory { public: virtual ~Factory() {} virtual std::unique_ptr<Product> createProduct() = 0; }; class ConcreteFactoryA : public Factory { public: std::unique_ptr<Product> createProduct() override { return std::make_unique<ConcreteProductA>(); } }; class ConcreteFactoryB : public Factory { public: std::unique_ptr<Product> createProduct() override { return std::make_unique<ConcreteProductB>(); } }; ``` 4. 在客户端代码使用具体工厂创建具体产品。 ```c++ int main() { std::unique_ptr<Factory> factory = std::make_unique<ConcreteFactoryA>(); std::unique_ptr<Product> product = factory->createProduct(); product->operation(); return 0; } ``` 这就是工厂模式的基本实现方式。通过这种方式,我们可以将对象的创建过程与客户端代码分离,从而更好地实现模块化和可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值