创建型设计模式:工厂方法、简单工厂、抽象工厂
1. 前言
设计模式,对于像java这种面向对象的语言来说,个人感觉是比较重要的。尤其在构建大型项目,设计模式的优点不言而喻。那么设计模式是什么?解决了软件工程中的什么问题?要想学一门东西,学一个知识点,我觉得首先得了解这个东西(知识、技术)它解决了什么问题,如果没有这门技术,那之前的做法是什么(历史)。
设计模式(Design Patterns)是软件工程中用于解决常见问题的通用设计和编程方法。它通常以对象和类为中心,通过抽象化来解决在软件设计中反复出现的某类问题。
设计模式大多依赖于面向对象编程中的一些概念和机制,如继承、多态、封装等,这些是面向对象语言的特性。而过程化语言如C语言,则缺乏这些面向对象的特性,所以应用设计模式比较困难,而java这种语言就非常适合使用设计模式来完成对代码的编写。
我觉得使用设计模式来进行编码,其实就是为了“让维护代码的后来者同事的心情更好”,总比那种if else不断的,不写注释的,写了那种让人懵逼的注释的强些。至少在结构上是清晰的,让人有一丝清爽感,而不是漫无天际的堆砌代码,一个类中的一个方法给你整上千行(被这样的代码整怕了@dog狗头)。
设计模式的主要优点就是:
- 代码复用性高,可重用已有的设计和代码。
- 可维护性好,各部分职责明确。
- 扩展性好,可按需扩展部分功能。
- 低耦合度,降低模块之间的依赖性。
学习设计模式可能需要了解的知识:
- 类图
类图中6种关系,继承、实现、关联、依赖、组合、聚合。http://ytvz.cn/6thsqI
2. 工厂方法模式
上面说学一门知识就要先了解它解决的问题,以及它的历史。那么,在学设计模式的时候,我觉得首先得弄清这个设计模式解决了什么问题(作用、应用场景)
工厂方法模式的作用:简单的理解就是创建对象。
名字就已经可以看出端倪,工厂它就是生产各种产品的地方。在OOP的语言中,对象其实就可以理解为产品(对象中封装了各种属性和功能,和现实中的产品对比是差不多,比如手机这个产品它有规格spec【摄像头像素、电池容量等等】,它也有功能【打电话、发短信等等】)。既然其作用就是为了创建对象,所以它是属于创建型的设计模式,当然简单工厂、抽象工厂都属于创建型。
相信java 程序员,尤其是web开发都接触使用过 spring
框架。我们大都是在业务处理类上标注@Service
注解使之成为spring
的一个Bean对象。spring
的BeanFactory
接口其实就是工厂模式实现的,就是为了实例化一个一个的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
形式。其实简单工厂模式是工厂方法模式的一种扩展。
简单的看下类图:
简单看下代码:
/**
* 简单工厂
*/
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();
//苹果手机发短信
//苹果手机听音乐
//苹果手机上网
}
}