1. 首页 > 手游资讯

简单工厂、工厂方式、抽象工厂 工厂类和简单工厂类区别

作者:admin 更新时间:2024-10-26
摘要:简单工厂模式简单工厂模式定义简单工厂模式是指一个工厂对象决定创建哪个产品类实例,但它不属于GOF23设计模式。简单工厂适用于工厂类负责创建较少对象的场景,客户端,简单工厂、工厂方式、抽象工厂 工厂类和简单工厂类区别

 

各位老铁们,大家好,今天由我来为大家分享简单工厂、工厂方法、抽象工厂,以及的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!

简单工厂模式

简单工厂模式定义

简单工厂模式是指一个工厂对象决定创建哪个产品类实例,但它不属于GOF23设计模式。简单工厂适用于工厂类负责创建较少对象的场景,客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑。

在JDK源代码中,Calendar使用了一个简单工厂。通过getInstance()的几个重载方法获取Calendar实例。但创建Calendar类实例的逻辑在createCalendar方法中。我们可以看一下它的实现代码:

/** * 获取具有指定时区和区域设置的日历。 * 返回的日历基于给定时区和给定区域设置的当前时间。 * * @param zone 要使用的时区* @param aLocale 周数据的区域设置* @return a Calendar。 */public static Calendar getInstance(TimeZone zone, Locale aLocale){ return createCalendar(zone, aLocale);}private static Calendar createCalendar(TimeZone zone, Locale aLocale){ CalendarProviderprovider=LocaleProviderAdapter. getAdapter(CalendarProvider.class, aLocale) .getCalendarProvider(); if (provider !=null) { try { returnprovider.getInstance(zone, aLocale); } } catch (IllegalArgumentException iae) { //回退到默认实例化} } Calendar cal=null; if (aLocale.hasExtensions()) { String caltype=aLocale.getUnicodeLocaleType('ca'); if (caltype !=null) { switch (caltype) { case 'buddhist': cal=new BuddhaCalendar(zone , aLocale);休息; case 'japanese': cal=new JapaneseImperialCalendar(zone, aLocale);休息; case 'gregory': cal=new GregorianCalendar(zone, aLocale);休息; } } } if (cal==null) { //如果没有显式指定已知的日历类型, //执行传统方式创建Calendar: //为th_TH 语言环境创建佛教日历, //为ja_JP_JP 语言环境创建JapaneseImperialCalendar,或者//适用于任何其他语言环境的GregorianCalendar。 //NOTE: 语言、国家和变体字符串被保留。 if (aLocale.getLanguage()=='th' aLocale.getCountry()=='TH') { cal=new BuddhaCalendar(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实例类之间的关系如下:

简单工厂的缺点

工厂类职责比较重,不容易扩展过于复杂的产品结构。

工厂方法模式

工厂方法模式

工厂方法模式定义

工厂方法模式是指定义一个用于创建对象的接口,但让实现这个接口的类决定实例化哪个类。工厂方法将类的实例化推迟到子类。在工厂方法模式中,用户只需要关心所需产品对应的工厂,而不必关心创建细节,并且添加新产品符合开闭原则。

让我们用代码来实现工厂方法。首先我们定义JavaCourse和PythonCourse。由于课程遵循统一规范,因此我们定义了ICourse接口。

public interface ICourse { /** * 录制视频* @return */void record();} public class JavaCourse Implements ICourse { public void record() { System.out.println('录制Java 课程'); } }} public class PythonCourse 实现ICourse { public void record() { System.out.println('记录Python 课程'); }}当用户需要使用某个课程实例时,我们仍然交给工厂来创建。它与简单的工厂不同。我们为每个课程创建一个对应的工厂,课程的实例化放在对应的工厂中,并且这些工厂都实现了相同的工厂接口。当用户需要获取课程实例时,只需要指定工厂即可获取对应的课程实例。

/** * 工厂模型* 由Zerlinda 创建。 */公共接口ICourseFactory { ICourse create();} 公共类JavaCourseFactory 实现ICourseFactory { public ICourse create() { return new JavaCourse(); } }} 公共类PythonCourseFactory 实现ICourseFactory { 公共ICourse create() { return new PythonCourse(); }这是工厂方法模式的实现。

通过类图关系,我们可以更清晰的看到他们的关系:

工厂方法适用场景

创建对象需要大量重复代码。客户端(应用程序层)不依赖于产品类实例如何创建和实现的细节。类通过其子类指定创建哪个对象工厂方法缺点

类很容易过多,从而增加复杂性。它增加了系统的抽象性和理解难度。

抽象工厂模式

抽象工厂模式

抽象工厂模式定义

抽象工厂模式提供了一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的特定类。客户端(应用程序层)不依赖于产品类实例如何创建和实现等细节。强调的是,一系列相关的产品对象(属于同一产品系列)一起使用来创建需要大量重复代码的对象。需要提供一个产品类库,所有产品都以相同的接口出现,这样客户端不依赖于具体的实现。

产品层次结构和产品系列图

在第二张图中,x轴代表产品系列,y轴代表产品级别。在产品家族为西数CPU的工厂里,可以看到对应的产品级别包括西数主板、西数硬盘、西数CPU。同样,在三星CPU工厂,对应的产品级别包括三星主板、三星硬盘、三星CPU。因此,产品系列是指某个特定工厂(如三星、西数、希捷等)生产的一系列产品,产品级别是指同一工厂生产的不同类型的产品(如主板、硬盘) 、CPU 等)。

明确了产品层次和产品家族后,我们再来看看抽象工厂模式。工厂是一个外部接口,它提供了一种创建一系列相关或相互依赖的对象的方法。通过选择不同的工厂,用户可以获得相应工厂的产品族的对象。

抽象工厂的缺点

它指定了可以创建的所有产品集合。产品族中扩展新产品比较困难,需要修改抽象工厂的接口。它增加了系统的抽象性和理解难度。实际需求升级产品层次是很正常的。我们可以根据实际情况不遵循开闭原则,只要不频繁升级即可。为什么不每六个月或每年升级一次代码?

在一个简单的工厂中,一个工厂可以返回不同的产品。在工厂方法中,用户指定工厂,工厂只返回特定的产品。可以说,简单工厂是产品的工厂,工厂方法是简单工厂的工厂。那么什么是抽象工厂呢?抽象工厂可以说是工厂方法的工厂。抽象工厂的实现工厂类可以提供一系列相关或相互依赖的产品。简单工厂、工厂方法、抽象工厂,它们是递进关系。它们的相似之处在于用户不需要关心具体的实现细节,但它们的不同之处在于工厂提供的产品实例是不断扩展的。

我们看一下抽象工厂的代码实现。我们的业务包括Java课程系列和Python课程系列。每个课程系列都包括现场课程、笔记和录制视频。所以我们这里的产品级别包括课程、笔记和视频。产品系列是Java 和Python。由于每种产品都有统一的规范,所以我们首先为每一类产品定义一个接口规范。

public interface ICourse { /** * 录制视频* @return */void record();}/** * 课堂笔记* 由Zerlinda 创建。 */public interface INote { void edit();}/** * 录制和播放视频* 由Zerlinda 创建。 */public interface IVideo { void record();} 接下来,每个产品系列都有产品。这里我们只贴出Java家族的产品实现代码。

public class JavaCourse 实现ICourse { public void record() { System.out.println('录制Java 课程'); }} public class JavaNote 实现INote { public void edit() { System.out.println('编写Java 笔记' ); }}public class JavaVideo 实现IVideo { public void record() { System.out.println('录制Java 视频'); }}同样,Ptyhon家族也有自己的产品实现。

接下来我们创建一个抽象工厂,即创建一个提供一系列相关或相互依赖的产品的接口。

/** * 抽象工厂是用户的主要入口* Spring中使用最广泛的设计模式之一* 易于扩展* 由Zerlinda创建。 */public Abstract class CourseFactory { public void init(){ System.out.println('初始化基础数据');受保护的抽象INote createNote(); protected abstract IVideo createVideo();} 每个产品族都有一个对应的工厂来实现这个抽象工厂,并为这个产品族提供一系列的产品。

公共类JavaCourseFactory 扩展了CourseFactory { 公共INote createNote() { super.init(); }返回新的JavaNote(); } 公共IVideo createVideo() { super.init();返回新的JavaVideo(); }} 公共类PythonCourseFactory 扩展了CourseFactory { 公共INote createNote() { super.init();返回新的PythonNote(); } 公共IVideo createVideo() { super.init();返回新的PythonVideo();到这里,大家都熟悉了简单工厂和工厂方法了,你对抽象工厂有清楚的认识了吗?欢迎大家留言一起讨论!

点点滴滴都是爱