ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

设计模式:JDK中的简单工厂

2019-03-07 22:53:20  阅读:218  来源: 互联网

标签:JDK class 工厂 aLocale Video cal new 设计模式 public


简介

简单工厂虽然不属于GOF23中设计模式,但却是非常简单、基础、常用的一种。
一般由一个工厂类、一个产品基类、多个产品子类构成。由工厂对象决定创建哪种产品类的实例,调用者只需要和工厂类交互。

举例

例如,我们现在有一个视频工厂,你无需直接创建具体的视频对象,工厂自会为你安排妥当。
基类,规定必要属性和抽象方法。

public abstract class Video {
    private String name;
    private String describe;

    public abstract void produce();
}

产品子类,实现抽象方法。

public class JavaVideo extends Video {
    public void produce() {
        System.out.println("This is Java class.");
    }
}
public class PythonVideo extends Video {
    public void produce() {
        System.out.println("This is python class.");
    }
}

工厂类,根据参数创建实例。

public class VideoFactory {
    public Video getInstance(String type) {
        if ("Java".equalsIgnoreCase(type)) {
            return new JavaVideo();
        } else if ("Python".equalsIgnoreCase(type)) {
            return new PythonVideo();
        }
        return null;
    }
}

客户端,只需要调用工厂方法并传参。

public class Test {
    public static void main(String[] args) {
        VideoFactory videoFactory = new VideoFactory();
        Video video = videoFactory.getInstance("Java");
        video.produce();
        video = videoFactory.getInstance("Python");
        video.produce();
    }
}

如上,工厂类的实例创建方法可以通过接收如String、int这样的标示参数创建对象,但这样不满足开闭原则,需要扩展子类时需要修改工厂类,无法对修改关闭。但如果将参数换成Class类型,直接传入你想创建的产品子类,工厂类就可以通过反射直接创建实例,可以一定程度上的满足开闭原则。

public class VideoFactory {
    public Video getVideo(Class clazz) {
        Video video = null;
        try {
            video = (Video) Class.forName(clazz.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return video;

    }
}

这样一来,客户端的调用方法随之变为:

public class Test {
    public static void main(String[] args) {
        VideoFactory videoFactory = new VideoFactory();
        Video video = videoFactory.getVideo(JavaVideo.class);
        video.produce();
    }
}

Java中的Calendar类,在创建Calendar实例时,就使用了简单工厂。

private static Calendar createCalendar(TimeZone zone, Locale aLocale) {
    ... ...
	Calendar cal = null;
    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;
			}
		}
	}
	if (cal == null) {
		if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
			cal = new BuddhistCalendar(zone, aLocale);
		} else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja" && aLocale.getCountry() == "JP") {
			cal = new JapaneseImperialCalendar(zone, aLocale);
		} else {
			cal = new GregorianCalendar(zone, aLocale);
		}
	}
	return cal;
}

Calendar的UML图如下,
在这里插入图片描述
有三个子类BuddhistCalendar,JapaneseImperialCalendar和GregorianCalendar。所以使用者在创建Calendar时,并不需要特别创建某一具体的Calendar,工厂会根据其时区等属性,自动生产合适的Calendar对象。

标签:JDK,class,工厂,aLocale,Video,cal,new,设计模式,public
来源: https://blog.csdn.net/weixin_41657493/article/details/88322188

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有