当前位置: 首页 > news >正文

【设计模式笔记10】:简单工厂模式示例

文章目录

      • 简单工厂模式示例
        • 示例1:电视机工厂
        • 示例2:图表库工厂
      • 在JDK中的应用:`java.util.Calendar`

简单工厂模式示例

示例1:电视机工厂

接续上一节的电视机场景,我们来看一个完整的代码实现。

  • 代码实现:

    // 角色1: 抽象产品 (Product)
    // 定义电视机的通用行为:播放
    interface Product {public void play(); 
    }// 角色2: 具体产品A (ConcreteProductA)
    // 海尔电视机
    class ConcreteProductA implements Product {@Overridepublic void play() {System.out.println("海尔电视机播放中......");}
    }// 角色2: 具体产品B (ConcreteProductB)
    // 海信电视机
    class ConcreteProductB implements Product {@Overridepublic void play() {System.out.println("海信电视机播放中......");}
    }// 角色3: 工厂类 (Factory)
    class Factory {// 提供生产产品的静态方法public static Product produce(String brand) throws Exception {if (brand.equalsIgnoreCase("Haier")) {System.out.println("电视机工厂生产海尔电视机!");return new ConcreteProductA();} else if (brand.equalsIgnoreCase("Hisense")) {System.out.println("电视机工厂生产海信电视机!");return new ConcreteProductB();} else {// 对于无法生产的品牌,抛出异常throw new Exception("对不起,暂不能生产该品牌电视机!");}}
    }
    
  • 客户端调用:

    // 测试类 (客户端)
    public class SimpleFactory {public static void main(String[] args) {try {// 客户端向工厂请求产品,只需要提供品牌名Product tv = Factory.produce("Haier");// 客户端直接使用产品,无需关心其具体类型和创建过程tv.play();// 更换品牌也只需修改参数// Product tv2 = Factory.produce("Hisense");// tv2.play();} catch (Exception e) {System.out.println(e.getMessage());}}
    }
    
  • 运行效果:

    电视机工厂生产海尔电视机!
    海尔电视机播放中......
    
示例2:图表库工厂
  • 背景需求:

    • Sunny软件公司要开发一套图表库,提供柱状图、饼状图、折线图等不同外观的图表。
    • 设计目标是为应用系统开发者提供一套灵活易用的图表库,并且可以较为方便地对图表库进行扩展,以便将来增加新类型的图表。
  • 初始设计 (反面教材):

    • 最初,可能将所有图表的创建和显示逻辑都耦合在一个Chart类中。
    // 违反单一职责和开闭原则的设计
    public class Chart {private String type; // 图表类型// 构造函数中根据类型进行不同的初始化public Chart(Object[][] data, String type) {this.type = type;if (type.equalsIgnoreCase("histogram")) {// 初始化柱状图} else if (type.equalsIgnoreCase("pie")) {// 初始化饼状图} else if (type.equalsIgnoreCase("line")) {// 初始化折线图}}// 显示方法中根据类型进行不同的显示public void display() {if (this.type.equalsIgnoreCase("histogram")) {// 显示柱状图} else if (this.type.equalsIgnoreCase("pie")) {// 显示饼状图} else if (this.type.equalsIgnoreCase("line")) {// 显示折线图}}
    }
    
    • 问题分析: 这个Chart类职责过重,既负责创建(初始化)又负责显示。而且,每当需要增加一种新的图表类型时,都必须修改这个类的构造函数和display方法,违反了开闭原则
  • 使用简单工厂模式重构:

    • 模式角色分析:
      • 抽象产品 (Product): Chart 接口,定义所有图表都必须具备的 display() 方法。
      • 具体产品 (ConcreteProduct): HistogramChart, PieChart, LineChart 等类,分别实现Chart接口,负责各自图表的具体显示逻辑。
      • 工厂 (Factory): ChartFactory 类,提供一个静态方法 getChart(String type),根据传入的类型字符串创建并返回具体的图表对象。
  • 重构后代码实现:

    // 抽象产品:Chart接口
    public interface Chart {public void display();
    }// 具体产品:HistogramChart, PieChart, LineChart 类(代码略,各自实现display方法)// 工厂类:ChartFactory
    public class ChartFactory {// 静态工厂方法public static Chart getChart(String type) {Chart chart = null;if (type.equalsIgnoreCase("histogram")) {chart = new HistogramChart();System.out.println("初始化设置柱状图!");} else if (type.equalsIgnoreCase("pie")) {chart = new PieChart();System.out.println("初始化设置饼状图!");} else if (type.equalsIgnoreCase("line")) {chart = new LineChart();System.out.println("初始化设置折线图!");}return chart;}
    }
    
  • 客户端调用:

    class Client {public static void main(String[] args) {Chart chart;// 客户端通过工厂获取实例,实现了创建和使用的分离chart = ChartFactory.getChart("line"); chart.display(); // 调用产品的功能}
    }
    
  • 运行效果:

    初始化设置折线图!
    显示折线图!
    

在JDK中的应用:java.util.Calendar

简单工厂模式(静态工厂方法)在Java的JDK源码中也有广泛应用。一个典型的例子就是java.util.Calendar类。

  • 源码分析:

    • 我们获取Calendar实例时,并不是通过new Calendar()Calendar是抽象类,无法直接new),而是通过调用它的静态方法 Calendar.getInstance()
    import java.util.Calendar;public class Factory {public static void main(String[] args) {// getInstance() 就是一个静态工厂方法Calendar cal = Calendar.getInstance();System.out.println("年: " + cal.get(Calendar.YEAR));// 月份从0开始,需要+1System.out.println("月: " + (cal.get(Calendar.MONTH) + 1)); System.out.println("日: " + cal.get(Calendar.DAY_OF_MONTH));}
    }
    
  • 内部机制:

    • getInstance() 方法会根据系统当前的区域设置(Locale)和时区(TimeZone)等信息,在内部决定具体创建并返回哪一个Calendar的子类实例(例如,在大多数情况下是GregorianCalendar)。
    • 这样,客户端代码完全不需要关心底层具体使用的是哪种日历实现,只需要与Calendar这个抽象类进行交互即可。这极大地提高了代码的灵活性和可维护性。
http://www.dtcms.com/a/544214.html

相关文章:

  • wordpress多站批量发布wordpress 图像描述
  • 永宝网站建设招聘信息松江做移动网站
  • 云手机 基于云计算的虚拟手机
  • 广州网站制作哪家专业网站开发分为哪几种类型
  • server 2012 做网站常州市新北区建设与管理局网站
  • 百度的网站网址做网站所用的工具
  • 网站统计功能设计旭泽建站
  • 网站建设心得8000字权威发布图片红字
  • 阿里做网站重庆市住房和城乡建设人才促进网
  • 个人业务网站教程合肥响应式网站建设方案
  • 广州建站业务公司亚马逊 wordpress
  • 北京知名网站建设wordpress二开
  • 做公众号要不要有自己的网站网站开发seo要求
  • 旅游网站ppt应做的内容上海猎头公司名单
  • 网站建设提案天空人体网站怎么做
  • 建设网站一般要多钱建设小说网站小说源
  • 东莞长安网站湖北网站建设的释义
  • 合肥地区建网站公司网站做多个页面
  • 如何查企业做网站是否备案过网站免费建立
  • 大连网站设计报价微信开店哪个平台好
  • 3 建设营销型网站流程西安百度关键词优化排名
  • 学校网站建设意义有哪些免费咨询的英文
  • 网站怎么在微博推广急求一张 网站正在建设中的图片
  • 网站定制文章列表项怎么做站长之家ppt模板
  • 百度网站制作公司学校网站建设情况
  • 哪个做企业网站网站数据报表
  • 外贸网站教程微信开发者平台小程序
  • 网站开发专业怎么样自己搭建网站服务器
  • 网站视频提取一般可以在哪些网站做推广
  • 荣县网站开发温州微网站制作公司推荐