积跬步至千里

创建型设计模式:工厂方法、简单工厂、抽象工厂

1. 前言

设计模式,对于像java这种面向对象的语言来说,个人感觉是比较重要的。尤其在构建大型项目,设计模式的优点不言而喻。那么设计模式是什么?解决了软件工程中的什么问题?要想学一门东西,学一个知识点,我觉得首先得了解这个东西(知识、技术)它解决了什么问题,如果没有这门技术,那之前的做法是什么(历史)。

设计模式(Design Patterns)是软件工程中用于解决常见问题的通用设计和编程方法。它通常以对象和类为中心,通过抽象化来解决在软件设计中反复出现的某类问题。

设计模式大多依赖于面向对象编程中的一些概念和机制,如继承、多态、封装等,这些是面向对象语言的特性。而过程化语言如C语言,则缺乏这些面向对象的特性,所以应用设计模式比较困难,而java这种语言就非常适合使用设计模式来完成对代码的编写。
我觉得使用设计模式来进行编码,其实就是为了“让维护代码的后来者同事的心情更好”,总比那种if else不断的,不写注释的,写了那种让人懵逼的注释的强些。至少在结构上是清晰的,让人有一丝清爽感,而不是漫无天际的堆砌代码,一个类中的一个方法给你整上千行(被这样的代码整怕了@dog狗头)。

设计模式的主要优点就是:

  • 代码复用性高,可重用已有的设计和代码。
  • 可维护性好,各部分职责明确。
  • 扩展性好,可按需扩展部分功能。
  • 低耦合度,降低模块之间的依赖性。

学习设计模式可能需要了解的知识:

  1. 类图
    类图中6种关系,继承、实现、关联、依赖、组合、聚合。http://ytvz.cn/6thsqI

2. 工厂方法模式

上面说学一门知识就要先了解它解决的问题,以及它的历史。那么,在学设计模式的时候,我觉得首先得弄清这个设计模式解决了什么问题(作用、应用场景)

工厂方法模式的作用:简单的理解就是创建对象。

名字就已经可以看出端倪,工厂它就是生产各种产品的地方。在OOP的语言中,对象其实就可以理解为产品(对象中封装了各种属性和功能,和现实中的产品对比是差不多,比如手机这个产品它有规格spec【摄像头像素、电池容量等等】,它也有功能【打电话、发短信等等】)。既然其作用就是为了创建对象,所以它是属于创建型的设计模式,当然简单工厂、抽象工厂都属于创建型。

相信java 程序员,尤其是web开发都接触使用过 spring 框架。我们大都是在业务处理类上标注@Service注解使之成为spring的一个Bean对象。springBeanFactory接口其实就是工厂模式实现的,就是为了实例化一个一个的Bean,它隐藏了bean的实例化和生命周期管理细节,给上层应用提供了简单的bean使用方法。

从一个简单的小例子出发,体验一下工厂方法设计模式:
简单类图:

/**
 * 手机产品接口
 */
public interface Phone {

    /**
     * 发短信
     */
    void sendMsg();

    /**
     * 听音乐
     */
    void listenMusic();

    /**
     * 上网
     */
    void internetSurf();
}
/**
 * 华为手机实现
 */
public class HuaWeiPhone implements Phone {
    @Override
    public void sendMsg() {
        System.out.println("华为手机发短信");
    }

    @Override
    public void listenMusic() {
        System.out.println("华为手机听音乐");
    }

    @Override
    public void internetSurf() {
        System.out.println("华为手机上网");
    }
}

/**
 * 苹果手机实现
 */
public class ApplePhone implements Phone{
    @Override
    public void sendMsg() {
        System.out.println("苹果手机发短信");
    }

    @Override
    public void listenMusic() {
        System.out.println("苹果手机听音乐");
    }

    @Override
    public void internetSurf() {
        System.out.println("苹果手机上网");
    }
}
/**
 * 抽象手机工厂
 */
public abstract class AbstractPhoneFactory {

    /**
     * 生产手机对象的泛型方法
     * 用 extends 协变,来标明返回类型必须是 Phone 或其子类
     * @param clazz
     * @param <T>
     * @return
     */
    protected abstract <T extends Phone> T createPhone(Class<T> clazz);

}

/**
 * 具体的手机工厂类
 */
public class PhoneFactory extends AbstractPhoneFactory {

    /**
     * 具体的生产手机这个对象的方法
     *
     * @param clazz
     * @param <T>
     * @return
     */
    @Override
    protected <T extends Phone> T createPhone(Class<T> clazz) {
        try {
            return (T) Optional.ofNullable(Class.forName(clazz.getName()).newInstance()).orElse(null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

public class Client {
    public static void main(String[] args) {
        AbstractPhoneFactory factory = new PhoneFactory();
        // 由具体的类决定实例化的对象
        // 就是为了生产对象
        Phone huaWeiPhone = factory.createPhone(HuaWeiPhone.class);
        huaWeiPhone.sendMsg();
        huaWeiPhone.listenMusic();
        huaWeiPhone.internetSurf();
        //华为手机发短信
        //华为手机听音乐
        //华为手机上网
    }
}

3.简单工厂模式

简单工厂模式(Simple Factory Pattern)其实也叫静态工厂模式,它其实就是去掉工程抽象类,将工厂类创建对象的方法设为静态static形式。其实简单工厂模式是工厂方法模式的一种扩展。

简单的看下类图:
image

简单看下代码:

/**
 * 简单工厂
 */
public class SimplePhoneFactory {
    public static <T extends Phone> T createPhone(Class<T> clazz) {
        try {
            return (T) Optional.ofNullable(Class.forName(clazz.getName()).newInstance()).orElse(null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
public class SimpleClient {
    public static void main(String[] args) {
        Phone applePhone = SimplePhoneFactory.createPhone(ApplePhone.class);
        applePhone.sendMsg();
        applePhone.listenMusic();
        applePhone.internetSurf();
        //苹果手机发短信
        //苹果手机听音乐
        //苹果手机上网
    }
}
posted @ 2023-07-30 23:29  大阿张  阅读(16)  评论(0编辑  收藏  举报