简单工厂并不属于GOF23中设计模式,更类似与一种编码习惯;但可以与之后的工厂模式进行对比归纳
- 定义:由一个工厂决定创建那个对象实例
- 适用场景
- 工厂类负责创建的对象比较少
- 客户端(应用层)只知道传入工厂类参数,对如何创建对象(逻辑)并不关心
- 优点
- 工厂的优点:解耦了应用层与实际对象的类(可能有多个),让应用层只依赖与接口与工厂,提高了稳定性
- 只需要知道要传入的参数,甚至都不用知道类名,就可以获取到所需要的对象
- 无须知道创建细节
- 缺点
- 工厂类的职责相对过重,一个工厂要创建多个对象
- 工厂内部有大量的 if 判断逻辑,违反了开闭原则
- 若要创建的对象多,容易出现工厂类爆炸
1.代码示例
1.1 接口及实现类
创建Vedio接口及其实现类JavaVedio,GolangVedio
public interface Vedio {
void play();
}
public class JavaVedio implements Vedio {
@Override
public void play() {
System.out.println("java...");
}
}
public class GolangVedio implements Vedio {
@Override
public void play() {
System.out.println("golang...");
}
}
1.2 创建实例实例对象
1)直接在应用层创建
- 这么做会让应用层直接依赖要创建的对象,直接表现就是要import具体对象的类
- 若要创建多个对象时,则会依赖多个对象,若对象一旦发生改变则很容易出现问题;强耦合
public static void main(String[] args) {
Vedio vedio = new JavaVedio();
vedio.play();
}
2)通过工厂创建对象
- 优点
- 解耦了应用层与对象类,只用依赖一个Factory就能创建多个对象
- 隐藏了对象创建细节,只用传入简单参数即可
- 缺点:工厂内的 if else 逻辑违反了开闭原则,若要创建新的对象则要添加新的分支语句
public class VedioFactory {
// 通过要创建对象的类名或标识来创建
public Vedio getVedio(String type) {
if (type.equalsIgnoreCase("java"))
return new JavaVedio();
else if (type.equalsIgnoreCase("golang"))
return new GolangVedio();
else
return null;
}
}
public static void main(String[] args) {
VedioFactory vedioFactory = new VedioFactory();
// 传入相应类名或指定标识即可
Vedio vedio = vedioFactory.getVedio("golang");
if (vedio != null) {
vedio.play();
}
}
3)工厂优化
public class VedioFactory {
// 通过反射来创建对象
public Vedio getVedio(Class clazz) throws Exception {
// Class的Instance是Object,要强转
return (Vedio)clazz.forName(clazz.getName()).newInstance();
}
}
public static void main(String[] args) throws Exception {
VedioFactory vedioFactory = new VedioFactory();
// 传入要创建对象的类的Class即可
Vedio vedio = vedioFactory.getVedio(JavaVedio.class);
if (vedio != null) {
vedio.play();
}
}
2.源码应用
Calendar.getInstance() 就是通过简单工厂创建了具体Calendar对象,只用传入TimeZone与Locale
public static Calendar getInstance(Locale aLocale)
{
return createCalendar(TimeZone.getDefault(), aLocale);
}
createCalendar() 方法就是简单的分支判断
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判断,看创建哪个对象
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;
}
本文标题:【设计模式】创建型:工厂模式(一)简单工厂
本文链接:https://blog.quwenai.cn/post/10171.html
版权声明:本文不使用任何协议授权,您可以任何形式自由转载或使用。







还没有评论,来说两句吧...