gof23——工厂设计模式详解

一、简单工厂(静态工厂)模式

简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定要创建哪一种产品类的实例,不属于gof23.简单工厂适用于工厂类创建对象较少的场景,且客户端只要传入工厂类的参数,对于如何创建对象并不关心。

假设现在我们有一个课程场景,有一个课程接口,和java课程和python课程两个实现类

public interface ICourse {
    /**
     * 录制课程视频
     */
    void record();
}
public class JavaCourse implements ICourse{
    /**
     * 录制课程视频
     */
    @Override
    public void record() {
        System.out.println("正在录制java课程视频");
    }
public class PythonCourse  implements ICourse{
    /**
     * 录制课程视频
     */
    @Override
    public void record() {
        System.out.println("正在录制python视频");
    }
}
public static void main(String[] args){
    ICourse course1=new JavaCourse();
    ICourse course2=new PythonCourse();
}

当我们的课程越来越多时,客户端的依赖就会变得越来越臃肿,因此我们需要想办法把这种依赖减弱,把创建细节隐藏起来。这里使用简单工厂对代码进行优化

public class CourseFactory {
    public static ICourse getCourse(String courseName){
        if("java".equals(courseName)){
            return new JavaCourse();
        }else if("python".equals(courseName)){
            return new PythonCourse();
        }
        return null;
    }
    public static void main(String[] args) {
        ICourse course1=CourseFactory.getCourse("java");
        ICourse course2=CourseFactory.getCourse("python");
    }
    
}

这样客户端就不需要去了解具体课程类的创建,直接通过工厂获取。但是如果现在我们在添加新的课程之后,仍然需要修改工厂的代码逻辑,这里我们可以采用反射进行优化。

public class CourseFactory {
    public static ICourse getCourse(String className){
       if(null!=className&&!"".equals(className)){
           try {
               return (ICourse) Class.forName(className).newInstance();
           } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
               e.printStackTrace();
           }
       }
       return null;
    }
}

但传入的是字符串,可控性有待提升,我们将传入值修改为限定的类对象

public class CourseFactory {
    public static ICourse getCourse(Class<? extends ICourse> clazz){
        if(null!=clazz){
            try {
                return clazz.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
       return null;
    }
}

简单工厂模式的缺点:工厂类的职责相对过重,不易于扩展过于复杂的产品结构

二、工厂方法模式

工厂方法模式(Factory Method Pattern)是指定义一个创建对象的接口,让实现这个接口的类来决定实例化哪个类,工厂方法模式让类的实例化推迟到子类中进行。在工厂方法模式中用户只需要关心所需产品对应的工厂,无须关系创建细节,而且加入新的产品是符合开闭原则。

工厂方法模式主要解决产品扩展的问题。在简单工厂中,随着产品链的丰富,工厂的职责会越来越多,不利于维护。通过工厂方法模式,我们将工厂进行拆分,一种产品一个工厂

public interface ICourseFactory {
    ICourse create();
}
public class JavaFactory implements ICourseFactory{
    @Override
    public ICourse create() {
        return new JavaCourse();
    }
}
public class PythonFactory implements ICourseFactory{
    @Override
    public ICourse create() {
        return new PythonCourse();
    }
}

工厂方法模式试用以下场景:

  • 创建对象需要大量的重复代码
  • 客户端(应用层)不依赖于类实例如何被创建、如何被实现等细节
  • 一个类通过其子类来指定创建哪个对象

缺点:

  • 类的个数容易过多,增加复杂度
  • 增加了系统的抽象性和理解难度

三、抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是指提供一个创建一系列相关或相互依赖对象的接口,无须指定它们的具体类。客户端(应用层)不依赖于产品类实例如何创建、如何被实现等细节,强调的是一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复代码。需要体哦那个一个产品类的库,所有产品以同样的接口出现,从而使客户端不依赖具体实现。

讲解抽象工厂前,我们需要了解两个概念:产品等级结构和产品族。以品牌为例,一个品牌下的所有产品属于一个产品族,一个产品的不同品牌属于一个等级结构

以课程为例,现在一个课程包括录播视频和课程笔记

public interface MyCourseFactory {
    IVideo createVideo();
    INote createNote();
}
public class JavaCourseFactory implements MyCourseFactory{
    @Override
    public IVideo createVideo() {
        return new JavaVideo();
    }

    @Override
    public INote createNote() {
        return new JavaNote();
    }
}
public class PythonCourseFactory implements MyCourseFactory{
    @Override
    public IVideo createVideo() {
        return new PythonVide();
    }

    @Override
    public INote createNote() {
        return new PythonNote();
    }
}
public class JavaNote implements INote{
    @Override
    public void edit() {
        System.out.println("java笔记");
    }
}
public class JavaVideo implements IVideo{
    @Override
    public void record() {
        System.out.println("java录播视频");
    }
}
public class PythonNote implements INote{
    @Override
    public void edit() {
        System.out.println("python笔记");
    }
}
public class PythonVide implements IVideo{
    @Override
    public void record() {
        System.out.println("python录播视频");
    }
}

如上代码所示,目前课程抽象工厂有java课程和python课程这两个产品族,其中java课程的笔记和python课程的笔记属于同一个产品等级结构,java课程视频和python课程视频也属于同一个产品等级结构。

抽象工厂模式相对于工厂方法模式来说,就是一个工厂能能够生产一系列相关或相互依赖的产品,可以减少工厂类的个数,但如果需要在工厂中添加新的产品则需要修改抽象工厂接口代码,不符合开闭原则,故抽象工厂模式的缺点有:

  • 规定了所有可能被创建的产品结合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。
  • 增加了系统抽象性和理解难度

在实际开发中我们应该根据具体情况灵活使用的设计模式,并不要求所有的代码都遵循设计原则,我们要考虑人力、时间、成本、质量,不能刻意去追求完美,但要在适当的场景遵循设计原则,这体现的是一种平衡取舍,可以帮助我们设计出更加优雅的代码结构。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值