** 2019-11-28 15:41:44 **
简单的工厂模式-Java设计模式(一)
简单工厂模式
简单工厂模式不是 23 种里的一种,简而言之,就是有一个专门生产某个产品的类。 更像是一种编码的风格和习惯。
适用范围
1.工厂类负责创建的对象比较少。 2.客户端(应用层)只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心。
优缺点
优点:只需要传入一个正确的参数,就可以获取你所需要的对象,无需知道其创建细节。 缺点:工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,无法满足开闭原则,对多个产品的扩展不利。
代码 & 结构图
动物例子
/**
* 动物接口
*/
public interface Animal {
void run();
}
public class Bird implements Animal {
@Override
public void run() {
System.out.println("鸟在天上飞");
}
}
public class Fish implements Animal {
@Override
public void run() {
System.out.println("鱼在水中游泳");
}
}
public class People implements Animal {
@Override
public void run() {
System.out.println("人在地上走");
}
}
工厂类
/**
* 工厂类
*/
public class AnimalFactory {
public static Animal createAnimal(String animal) {
switch (animal) {
case "fish":
return new Fish();
case "bird":
return new Bird();
case "people":
return new People();
default:
return null;
}
}
}
测试
public class Test {
public static void main(String[] args) {
Animal fish = AnimalFactory.createAnimal("fish");
// 调用方法
fish.run(); //输出结果: 鱼在水中游泳
}
}
UML结构图
源码 - simpleFactory分支
不同分支对应不同设计模式源码 github.com/nullaman/Ja…
JDK中的例子
Calendar类
Calendar.getInstance();
/**
* Gets a calendar using the default time zone and locale. The
* <code>Calendar</code> returned is based on the current time
* in the default time zone with the default
* {@link Locale.Category#FORMAT FORMAT} locale.
*
* @return a Calendar.
*/
public static Calendar getInstance()
{
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}
private static Calendar createCalendar(TimeZone zone,
Locale aLocale)
{
CalendarProvider provider =
LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
.getCalendarProvider();
if (provider != null) {
try {
return provider.getInstance(zone, aLocale);
} catch (IllegalArgumentException iae) {
// fall back to the default instantiation
}
}
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 no known calendar type is explicitly specified,
// perform the traditional way to create a Calendar:
// create a BuddhistCalendar for th_TH locale,
// a JapaneseImperialCalendar for ja_JP_JP locale, or
// a GregorianCalendar for any other locales.
// NOTE: The language, country and variant strings are interned.
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;
}