1、简单工厂、工厂方法、抽象工厂、单例模式

简单工厂、工厂方法、抽象工厂、单例模式

一、设计模式总览

1.开闭原则:对扩展开放,对修改关闭

2.单一职责原则:一个类、接口、方法只做一件事

3.依赖倒置原则:通过抽象使个各类,模块相互之间不影响,实现松耦合,尽量面向抽象,接口编程

4.接口隔离原则: 面向抽象基础上,一个接口只做某一类事情,客户端不应该依赖不同的端口

5.迪米特法则:最少知道原则,一个类对他所依赖的类知道的越少越好

6.里氏替换原则:子类可以扩展父类的功能,但不能修改父类已有的功能,避免继承泛滥

7.合成复用原则:尽量使用对象组合、聚合而尽量不适用继承

说明:

没有设计模式,我们的代码也可以运行,那我们为什么要学习设计模式呢?

设计模式对我们的代码逻辑并没有影响,但是利用设计模式可以让我们的代码变得更易读、更清晰、更优雅的代码,这一点很重要

二、Simple Factory Pattern简单工厂模式

1、简单工厂模式定义

简单工厂模式(Simple Factory Pattern)是指由一个工程对象决定创建出哪一种产品类的实例。

属于创建型模式,但它不属于GOF 23种设计模式。

我们来举例说明:

MyCourse接口(定义了一个record()方法):

package org.example.pattren.factory.simplefactory;

public interface MyCourse {
    void record();
}

JavaCourse类和PythonCourse类:实现了MyCourse接口

public class JavaCourse implements MyCourse {
   
    @Override
    public void record() {
   
        System.out.println("录制Java课程");
    }
}
public class PythonCourse implements MyCourse {
   
    @Override
    public void record() {
   
        System.out.println("录制Python课程");
    }
}

以上准备结束后,正常状况下我们通常会分别new一个对象来使用,

package org.example.pattren.factory.simplefactory;

public class Test {
   
    public static void main(String[] args) {
   
        MyCourse javaCourse = new JavaCourse();
        MyCourse pythonCourse = new PythonCourse();
        javaCourse.record();
        pythonCourse.record();
     }
}

这样使用显得比较繁琐,而且每用一个项目都需要new一个对象,但利用简单工厂模式我们可以忽略创建对象的逻辑,只需要传递一个正确的参数就可以生产需要的对象。下面我们创建一个工厂类:

public class CourseFactory {
   
    public MyCourse create(String name){
   
        if("Java".equals(name)){
   
            return new JavaCourse();
        } else if("Python".equals(name)){
   
            return new PythonCourse();
        } else{
   
            return null;
        }
    }
}

这样也实现了一个工厂类的基本功能,只要你传入对应的参数,就可以获得对应对象。但如果我们传入的参数有错误或并没有这个类这个只会返回null,并不会报错,因此这个工厂类还可以进行优化。

优化后的工厂类CourseFactory

package org.example.pattren.factory.simplefactory;

public class CourseFactory {
   
    public MyCourse create(String className){
   
        if(!(null == className || "".equals(className))){
   
            try {
   
                return (MyCourse)Class.forName(className).newInstance();
            } catch (Exception e) {
   
                e.printStackTrace();
            }
        }
        return null;
    }
}

上面优化后,利用了Java重要的技术:反射,并且加入异常处理,但这样的话,我们在调用函数是需要传入类的全路径,容易打错还很麻烦。。。我们就可以进一步优化工厂类,如下:

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

我们直接传入一个类,并且利用泛型通配符限制传入的参数必须是MyCourse及其子类(<? extends MyCourse>上线为MyCourse),同时有异常处理这样就比较完善,测试类中只需要传入想生产的类即可。

package org.example.pattren.factory.simplefactory;

import java.util.Calendar;

public class Test {
   

    public static void main(String[] args) {
   
      	MyCourse course = new CourseFactory().create(JavaCourse.class); // 只需要传入对应的class即可
        course.record();

        Calendar.getInstance();		//Calendar也利用了工厂类
    }
}

Calender类

if (aLocale.hasExtensions()) {
   
    String caltype = aLocale.getUnicodeLocaleType("ca");
    if (caltype != null) {
   
        switch (caltype) {
   
        case "buddhist":
        cal = new BuddhistCalendar(zone, aLocale);
            break;
        case "japanese":
            cal = new JapaneseImperialCalendar(zone, aLocale);
            break;
        case "gregory":
            cal = new GregorianCalendar(zone, aLocale);
            break;
        }
    }
}

2、简单工厂使用场景

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

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

3、简单工厂的优点

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

4、简单工厂的缺点

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

不易于扩展过于复杂的产品结构。

三、Factory Method Pattern工厂方法模式

1、工厂方法模式定义

工厂方法模式(Factory Method Pattern)是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类进行

属于创建型设计模式

工厂方法接口相比于简单工厂模式新添加了一个MyCourseFactory接口,接口内仅仅声明了一个create()方法用来创建一个MyCourse

public interface MyCourseFactory {
   
    MyCourse create();
}

同时定义JavaCourseFactory和PythonCourseFactory类,实现MyCourseFactory(工厂接口),将功能划分下去

public class JavaCourseFactory implements MyCourseFactory{
   
    @Override
    public MyCourse create() {
   
        return new JavaCourse();
    }
}
public class PythonCourseFactory implements MyCourseFactory{
   
    @Override
    public MyCourse create() {
   
        return new PythonCourse();
    }
}

上面两个类中的JavaCourse类和PythonCourse类就是讲解简单工厂时使用的类,这里不再展示

接下来我们演示一下工厂方法模式

public class Test {
   
    public static void main(String[] args) {
   
        MyCourseFactory factory = new PythonCourseFactory();
        MyCourse course = factory.create();
        course.record();
    }
}

工厂方法模式在实例化对象时只需要new对应的工厂类,并调用create()方法来创建对象

2、工厂方法模式适用场景

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

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

一个类通过其子类来制定创建哪个对象

3、工厂方法模式的优缺点

优点

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

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

缺点

类的个数容易过多,增加了代码结构的复杂度。

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

四、Abstarct Factory Pattern抽象工厂模式

1、抽象工厂模式的定义和使用

定义:抽象工厂模式是指提供一个创建一系列相关或互相依赖对象的接口,无需指定他们具体的类。

属于创建型设计模型。

我们还是用前面课程的例子,课程不应该只有录播,还应该提供笔记之类的功能,这里为教学演示不太复杂,我们只涉及录播和笔记。

我们将MyCourse接口的功能分开为MyVideo和MyNote

public interface  MyVideo {
   
    void record();	//录播
}
public interface MyNote {
   
    void edit();	//编辑
}

我们还需要一个课程工厂CourseFactory,这个工厂既可以interface也可以用abstract类修饰,这里如何选择呢?

如果工厂没有通用逻辑的话一般用interface(接口)修饰即可

工厂有通用逻辑就使用abstract(抽象类)修饰


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值