设计模式之简单工厂模式
来源:互联网 发布:java jsoup 爬虫实例 编辑:程序博客网 时间:2024/06/07 18:22
前言:
简单工厂模式是常用的设计模式,该模式解决了如何实例化对象的问题。
一. 简单工厂的简介:
1. 工厂的含义:工厂是一个负责创建对象的类。
2. 面向对象编程理解:
面向对象的编程,目的是为了让代码做到易维护、易扩展、易复用。
生活中的实例: 像活字印刷术一样,一行文字,可以替换任意一个,也可以在任意位置新增一个字,每个字还可以重复使用,这使得字与字之间的耦合度,降到最低。
在面向对象的编程中,用封装、继承、多态,来达到以上的目的,这就是面向对象的编程。设计模式就是为了更好的完成面向对象而服务的。
二. 简单工厂模式实例
案例:一个电子阅读器,中文模式和英文模式和日文模式等之间的语言切换功能的实现。
设计UML模型图:
- 产品的的抽象类:抽象类是具有相同属性和方法的提取类。本例中,所有的语言的阅读器都应该有显示show()功能,提取出来。
package com.pattern.service;/** * 多国语言阅读器接口 * @author 葫芦娃 * */public interface IReader { //显示内容 void show();}
2 . 产品类:实现了抽象类的方法,并对此方法加上自己特有的功能实现(体现出类与类之间的重载和多态)。
中文阅读器:
package com.pattern.impl;import com.pattern.service.IReader;/** * 汉语阅读器 * * @author 葫芦娃 * */public class ChineseReader implements IReader { @Override public void show() { System.out.println("汉语阅读器:我爱你"); }}
英文阅读器:
package com.pattern.impl;import com.pattern.service.IReader;/** * 英语阅读器 * * @author 葫芦娃 * */public class EnglishReader implements IReader { @Override public void show() { System.out.println("英语阅读器:I LOVE YOU"); }}
日文阅读器:
package com.pattern.impl;import com.pattern.service.IReader;/** * 日语阅读器 * * @author 葫芦娃 * */public class JapaneseReader implements IReader { @Override public void show() { System.out.println("日语阅读器:私はあなたを愛して"); }}
3 . 工厂类:包含必要的逻辑判断,根据客户端选择条件,动态的实例化产品类.
package com.pattern.factory;import com.pattern.impl.ChineseReader;import com.pattern.impl.EnglishReader;import com.pattern.impl.JapaneseReader;import com.pattern.service.IReader;/** * 简单工厂类 * * @author 葫芦娃 * */public class ReaderFactory { /** * 根据用户选择的语言,创建阅读器 * * @param language * @return IReader */ public static IReader createReader(String language) { IReader reader = null; switch (language) { case "Chinese": reader = new ChineseReader(); break; case "English": reader = new EnglishReader(); break; case "Japanese": reader = new JapaneseReader(); break; default: reader = new ChineseReader(); break; } return reader; } /** * 通过类名映射创建对象 * @param className * @return */ public static IReader createReaderByClassName(String className){ IReader reader = null; try { //通过反射的方式创建对象,解决分支判断问题 reader = (IReader) Class.forName(className).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return reader; }}
这里提供了两个方法作参考,第一个方法createReader()就是根据不同的情况,来判断创建哪一个语言的阅读器。
第二个方法createReaderByClassName()业实现了同样的功能,优点是利用“反射”的方式,通过传入不同的类名,创建与之对应对象。在实际的开发中,可以将输入的参数,保存在properties文件中,便于管理和维护,供你参考。
工厂类的作用:包含了必要的逻辑判断,根据客户端的选择条件,动态实例化相关的类。它解决了对在客户端创建对象过程的隐藏和封装,客户端无需了解对象的创建过程,直接通过参数,控制工厂,得到想要创建的对象实例。
简单工厂的缺点:每当新加一个产品,都要去修改工厂类,在工厂类中增加一个case分支条件,这就要修改原有代码,违反了开放-封闭原则。
开放-封闭原则:对扩展开放,对修改关闭的原则。新需求的增加不是要在原有代码上改来改去,而是要通过新增相关类的方式,实现对新功能的拓展,不影响原有功能的使用,降低代码间的耦合性。
4 . 客户端中的使用:
客户端不管用哪个产品类的实例,只需要把参数名(如“Chinese”)传递给工厂,工厂自动就给出了相应的实例。
package com.pattern.client;import com.pattern.factory.ReaderFactory;import com.pattern.impl.ChineseReader;import com.pattern.impl.EnglishReader;import com.pattern.impl.JapaneseReader;import com.pattern.service.IReader;/** * 客户端类:调用工厂创建实例 * * @author 葫芦娃 * */public class TestClient { public static void main(String[] args) { TestClient client = new TestClient(); // 通过关键字创建 client.testCreateReader(); //通过类名创建 client.testCreateReaderByClassName(); } //测试工厂模式创建对象 private void testCreateReader() { IReader cReader = ReaderFactory.createReader("Chinese"); cReader.show(); // 用户切换英语模式 IReader eReader = ReaderFactory.createReader("English"); eReader.show(); // 用户切换日语模式 IReader jReader = ReaderFactory.createReader("Japanese"); jReader.show(); } //测试通过反射的方式获取对象 private void testCreateReaderByClassName() { IReader cReader = ReaderFactory.createReaderByClassName("com.pattern.impl.ChineseReader"); cReader.show(); IReader eReader = ReaderFactory.createReaderByClassName(EnglishReader.class.getName()); eReader.show(); IReader jReader = ReaderFactory.createReaderByClassName(JapaneseReader.class.getName()); jReader.show(); }}
5 . 输出的结果:
汉语阅读器:我爱你英语阅读器:I LOVE YOU日语阅读器:私はあなたを愛して汉语阅读器:我爱你英语阅读器:I LOVE YOU日语阅读器:私はあなたを愛して
三. 总结:
简单工厂实现了对如何创建对象过程的封装,客户端不在关心对象是如何实例化的,只需通过工厂,传入相关的参数,实例化对象。
简单工厂的缺点也就暴露了出来,如果我在新增一个功能(如:西班牙语阅读器),那就必须修改工厂类。如何解决这个问题呢?在下一章的工厂模式(点击查看)中将解决这个问题。
- 设计模式 之简单工厂+ 工厂模式
- 设计模式之简单工厂设计模式
- 设计模式之简单工厂模式,工厂模式,策略模式
- 设计模式 之 简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂.
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 使用bochs调试grub2
- Fragment 跳转到 Activity 如何接收回来的数据
- (转)知乎:维度灾难
- mapreduce和shuffle详解
- hive lateral view语句
- 设计模式之简单工厂模式
- oracle数据库导入导出
- excel2013导入SQL
- Java并发容器之ArrayBlockingQueue
- spring集成redis
- 应用层协议的内容与基本原理
- 把妹需要勇敢,心有猛虎,细嗅蔷薇
- storm 1.1.0 与 kafka 2.10-0.10.2.1的安装部署
- WebLogic使用总结(七)——WebLogic部署Web应用并绑定域名