设计模式详解--工厂模式

 

设计模式详解--工厂模式

我们接下来会学习软件设计中的23种设计模式

其实绝大部分的设计模式通过名字你就可以看出来,都是在自然界中可以找得到影子的。设计模式也是伟大优秀的设计师从生活中抽丝剥茧找出复合人类思维模式且同样适用于软件设计的一种总结。至于为什么这么巧,我想更多地是因为面向对象思想的诞生吧,因为面向对象本身就是更符合人类思维方式的一种思想。

一提到工厂模式,恐怕很多人会脑中蹦出一大堆名词:

简单工厂模式、抽象工厂模式、工厂模式……

其实在GOF23种设计模式种,只有最后一个“工厂模式”才是真正属于他们中的一员,简单工厂模式和抽象工厂模式其实是工厂模式的一个变种。我们接下来会一一介绍。

工厂模式的总纲就是通过一个类似现实生活中的工厂生产产品一样,通过一个工厂类生产对象。这样符合代码高内聚,可复用的原则。

简单工厂模式:

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

 

情景模式:假设我们想要创建一个生产课程的工厂。

public class CourseFactory {

    public ICourse create(String name){
        if("java".equals(name)){
            return new JavaCourse();
        }else if("python".equals(name)){
            return new PythonCourse();
       }else {
           return null;
        }
    }
}

实体类java课程和python课程和课程接口如下

public interface ICourse {
    /**
     * 录制视频
     * @return
     */
    void record();
}
public class JavaCourse implements ICourse {

    public void record() {
        System.out.println("录制Java课程");
    }
}
public class PythonCourse implements ICourse {

    public void record() {
        System.out.println("录制Python课程");
    }
}

然后再写一个测试类让java和python课程进行录制:

public class SimpleFactoryTest {

    public static void main(String[] args) {

        ICourse course = new JavaCourse();
        course.record();


    }
}

代码运行结果:

这样我们就完成了简单工厂方法生产JAVA课程并调用其内方法

但是这么做有一个缺点,就是每增加一个课程(产品),就需要增加一个if else判断,当遇到大量产品的工厂方法时更是惨不忍睹,每增加一种产品都要对工厂类进行修改,不符合开闭原则。所以我们接下来对简单工厂进行改良。

第一种改良:

public class CourseFactory {


    public ICourse create(String className){
        try {
            if (!(null == className || "".equals(className))) {
                return (ICourse) Class.forName(className).newInstance();
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

  

}

通过反射来动态加载

实现类:

 

public class SimpleFactoryTest {

    public static void main(String[] args) {

        ICourseFactory factory = new ICourseFactory();
        ICourse course = factory.create("com.factory.JavaCourse");
        course.record();


    }
}

运行结果和上面的一致。

第二种改良

这种改良方法是通过泛型机制来实现的

工厂类:

public class CourseFactory {


    public ICourse create(Class<? extends ICourse> clazz){
        try {
            if (null != clazz) {
                return clazz.newInstance();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

}

实现类:

 public static void main(String[] args) {

        CourseFactory factory = new CourseFactory();
        ICourse course = factory.create(JavaCourse.class);
        course.record();

    }

输出结果和上面的一致。

总结:

简单工厂使用场景:

工厂类负责创建的对象较少

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

优点:只需要传入一个正确的参数,就可以获取你所需要的对象无需知道其创建的细节

缺点:工厂类的职责相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背开闭原则(常规做法),不易于扩展过于复杂的残品结构。

工厂方法模式

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

适用场景:创建对象需要大量的重复代码。

客户端(应用层)不依赖于产品类实例如何被创建、实现等细节,一个类通过其子类来指 定创建哪个对象

1.定义一个创建对象的接口

public interface ICourseFactory {

    ICourse create();

}

 

2.再创建两个生产工厂

public class JavaCourseFactory implements ICourseFactory {
    public ICourse create() {
        return new JavaCourse();
    }
}
public class PythonCourseFactory implements ICourseFactory {

    public ICourse create() {
        return new PythonCourse();
    }
}

3.测试类

public class FactoryMethodTest {

    public static void main(String[] args) {

        ICourseFactory factory = new PythonCourseFactory();
        ICourse course = factory.create();
        course.record();

        factory = new JavaCourseFactory();
        course = factory.create();
        course.record();

    }

}

4.运行结果

 

5.类图

可以看出接口只提供了方法,真正生产产品的类是一一对应的。以后要是新增加产品只需要增加两个类就好了

优点:用户只需要关心所需产品对应的工厂,无需关心创建细节。加入新产品符合开闭原则,提高了系统的可扩展性

缺点:类的个数容易过多,增加了代码结构的复杂度。增加了系统的抽象性和理解难度

抽象工厂方法模式

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

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

适用场景:客户端(应用层)不依赖与产品类如何被创建、实现等细节,强调一系列相关的产品对象(属于同一产品族)一起使用,创建对象需要大量重复的代码。抽象工厂模式与工厂模式最大的区别就是抽象工厂模式强调一个产品族,即一系列产品。

下面依旧是拿上面的课程作为举例,每种课程都可以提供录制和编辑笔记两种产品

1.创建课程工厂(抽象工厂)

public interface CourseFactory {

    INote createNote();

    IVideo createVideo();

}

2.创建笔记、视频接口(一些列产品中的组成部分)

public interface INote {
    void edit();
}
public interface IVideo {
    void record();
}

3.创建具体实例

public class JavaVideo implements IVideo {
    public void record() {
        System.out.println("录制Java视频");
    }
}

 

public class JavaVideo implements IVideo {
    public void record() {
        System.out.println("录制Java视频");
    }
}

4.创建工厂(某一系列产品工厂,专门生产这个系列产品)

public class JavaCourseFactory implements CourseFactory {

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

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

 

python课程我就不放上去了

编写测试类

public class AbstractFactoryTest {

    public static void main(String[] args) {

        CourseFactory factory = new JavaCourseFactory();

        factory.createNote().edit();
        factory.createVideo().record();

    }

}

最终的类文件列表如下

 

类图:

运行结果:

总结:

抽象工厂模式更关注的是产品族的创建,在本例中。想要java课程的产品族,就用JavaCourseFactory生产java note和java 视频两种产品,想要python的同理。

优点:具体产品在应用层代码隔离,无需关心创建细节。将一个系列的产品族统一到一起创建

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

以上就是关于工厂模式的介绍,有不当之处烦请各位留言指正。

下一篇是单例模式的学习

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值