1.ファクトリーモデルの歴史的起源
実生活では、原始社会は自給自足(工場なし)、小規模農業社会(単純な工場、民俗ワインショップ)、産業革命組立ライン(工場方式、自己生産および自己販売)、現代の産業チェーン鋳造所(要約)であることは誰もが知っていますファクトリー、フォックスコン)
2.シンプルなファクトリーモデル
Simple Factory Pattern(Simple Factory Pattern)は、作成される製品インスタンスの種類を判別するためのファクトリオブジェクトを参照しますが、GOF、23の設計パターンには属していません。参考資料
シンプルファクトリは、ファクトリクラスが作成するオブジェクトの数が少なく、クライアントがファクトリクラスのパラメータを渡すだけで、オブジェクトの作成方法のロジックを気にする必要がないシナリオに適しています。
まず、コースの標準ICourseインターフェイスを定義できます
public interface ICourse {
/** 录制视频 */
public void record();
}
Javaコース実装JavaCourseクラスを作成します。
public class JavaCourse implements ICourse {
public void record() {
System.out.println("录制 Java 课程");
}
}
CourseFactoryファクトリクラスを作成します。
public class CourseFactory {
public ICourse create(String name){
if("java".equals(name)){
return new JavaCourse();
}else if("python".equals(name)){
return new PythonCourse();
}else {
return null;
}
}
}
クライアントの呼び出しコードを変更します。
public class SimpleFactoryTest {
public static void main(String[] args) {
CourseFactory factory = new CourseFactory();
factory.create("java");
}
}
もちろん、呼び出しの便宜のために、ファクトリのcreate()を静的メソッドに変更できます。見てみましょう。
クライアント側の呼び出しは単純ですが、ビジネスが拡大し続け、フロントエンドコースを追加する必要がある場合は、ファクトリでcreate()を使用します。製品チェーンの豊富さに応じて、毎回コードロジックを変更する必要があります。開閉の原則に適合していません。したがって、単純なファクトリを引き続き最適化でき、反射テクノロジーを使用できます。
public class CourseFactory {
public ICourse create(String className){
try {
if (!(null == className || "".equals(className))) {
return (ICourse) Class.forName(className).newInstance();
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
クライアントの呼び出しコードを変更します。
public static void main(String[] args) {
CourseFactory factory = new CourseFactory();
ICourse course = factory.create("com.gupaoedu.vip.pattern.factory.simple factory.JavaCourse");
course.record();
}
最適化後、CourseFactoryのコードを変更することなく、製品が継続的に強化されます。ただし、メソッドパラメータが文字列であるという問題があり、制御性を改善する必要があり、必須の変換が必要です。コードをもう一度変更してみましょう。
public ICourse create(Class<? extends ICourse> clazz){
try {
if (null != clazz) {
return clazz.newInstance();
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
クライアントコードを最適化します。
public static void main(String[] args) {
CourseFactory factory = new CourseFactory();
ICourse course = factory.create(JavaCourse.class);
course.record();
}
クラス図をもう一度見てください。
単純なファクトリパターンもJDKソースコードに遍在しています。次に、Calendarクラスなどの例を見てみましょう。Calendar.getInstance()メソッドを見てください。Calendarの特定の作成クラスは次のとおりです。
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;
}
誰もが頻繁に使用するログバックもあります。LoggerFactorygetLogger()には複数のオーバーロードされたメソッドがあることがわかります。
public static Logger getLogger(String name) {
ILoggerFactory iLoggerFactory = getILoggerFactory();
return iLoggerFactory.getLogger(name);
}
public static Logger getLogger(Class clazz) {
return getLogger(clazz.getName());
}
単純な工場にも欠点があります。工場クラスの責任は比較的重く、過度に複雑な製品構造を拡張することは容易ではありません。