【デザインパターン】シンプルファクトリ、ファクトリメソッド、アブストラクトファクトリ

記事のディレクトリ

シンプルなファクトリ

  • 定義由一个工厂对象决定创建出哪一种产品类的实例
  • タイプ:作成タイプですが、GOF(Gang of Four)の23のデザインパターンに属していません。
  • シナリオの使用
    • ファクトリクラスは、より少ないオブジェクトを作成する責任があります
    • クライアント(アプリケーション層)は、ファクトリクラスに渡されたパラメータのみを認識し、オブジェクトロジックの作成方法を気にしません。
  • 利点:正しいパラメーターを渡すだけで、作成の詳細を知らなくても必要なオブジェクトを取得できます
  • 短所:ファクトリーカテゴリーの責任は比較的重いです。新製品を追加するには、ファクトリーカテゴリーの判断ロジックを変更する必要があり、開閉の原則に違反します。
  • コーディング
public abstract class Video {
    
    
    public abstract void produce();
}
/**
 * Java视频类
 */
public class JavaVideo extends Video {
    
    
    @Override
    public void produce() {
    
    
        System.out.println("Java。。。");
    }
}
/**
 * Python视频类
 */
public class PythonVideo extends Video {
    
    
    @Override
    public void produce() {
    
    
        System.out.println("Python。。。");
    }
}
/**
 * 生产实例工厂
 */
public class VideoFactory {
    
    
    public Video getVideo(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.getVideo("java");
        if (video == null) {
    
    
            return;
        }
        video.produce();
    }
}
==================================== 控制台输出 =======================================
Java。。。
  • UML类图
    単純なファクトリUMLクラス図
  • :UMLダイアグラムを見ると、非常に明確です。TestテストクラスはVideoファクトリのみを作成しますが、JavaとPythonはファクトリによって作成され、Testはファクトリを通じてJavaまたはPythonインスタンスを取得できます。欠点も明らかです。別のGo言語クラスに来た場合は、ファクトリを変更し、ファクトリを追加するたびに変更する必要があります。これはリスクをもたらし、開始と終了の原則に準拠していません。
  • 反射法の変換
public class VideoFactory {
    
    
    public Video getVideo(Class c){
    
    
        Video video = null;
        try {
    
    
            video = (Video) Class.forName(c.getName()).newInstance();
        } catch (InstantiationException e) {
    
    
            e.printStackTrace();
        } catch (IllegalAccessException e) {
    
    
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
    
    
            e.printStackTrace();
        }
        return video;
    }
}
/**
 * 只需要传入需要生成类的Class类型,工厂会通过反射返回实例对象
 */
public class Test {
    
    
    public static void main(String[] args) {
    
    
        VideoFactory videoFactory = new VideoFactory();
        Video video = videoFactory.getVideo(JavaVideo.class);
        if(video == null){
    
    
            return;
        }
        video.produce();
    }
}
  • JDKソースコードでの使用例:java.util.Calendar#createCalendar
	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;
	        }
	    }
	}

ファクトリメソッド

  • 定義:オブジェクトを作成するためのインターフェースを定義し、このインターフェースを実装するクラスに、インスタンス化するクラスを決定させます。工厂方法让类的实例化推迟到子类中进行
  • タイプ:作成
  • シナリオの使用
    • オブジェクトの作成には、多くの反復コードが必要です
    • クライアント(アプリケーション層)は、製品クラスインスタンスの作成方法と実装方法の詳細に依存しません
    • クラスは、そのサブクラスクラスを介して作成するオブジェクトを指定します
  • 利点
    • ユーザーは製品に対応する工場だけを気にする必要があり、作成の詳細を気にする必要はありません
    • 新製品の追加は開閉の原則に準拠し、スケーラビリティを向上させます
  • 短所
    • クラスの数が多すぎて複雑さが増すのは簡単です
    • システムの抽象化と理解の難しさが増した
  • コーディング

public abstract class Video {
    
    
    public abstract void produce();
}
/**
 * 三个实例对象
 */
public class FEVideo extends Video{
    
    
    @Override
    public void produce() {
    
    
        System.out.println("FE。。。");
    }
}
public class JavaVideo extends Video {
    
    
    @Override
    public void produce() {
    
    
        System.out.println("Java。。。");
    }
}
public class PythonVideo extends Video {
    
    
    @Override
    public void produce() {
    
    
        System.out.println("Python。。。");
    }
}
/**
 * 只制定规范契约,并不决定产生哪一种类的实例,产生哪一种实例完全交由子类实现
 */
public abstract class VideoFactory {
    
    
    public abstract Video getVideo();
}
/**
 * 只制定规范契约,并不决定产生哪一种类的实例,产生哪一种实例完全交由子类实现
 */
public class PythonVideoFactory extends VideoFactory {
    
    
    @Override
    public Video getVideo() {
    
    
        return new PythonVideo();
    }
}
public class JavaVideoFactory extends VideoFactory {
    
    
    @Override
    public Video getVideo() {
    
    
        return new JavaVideo();
    }
}
public class FEVideoFactory extends VideoFactory{
    
    
    @Override
    public Video getVideo() {
    
    
        return new FEVideo();
    }
}
public class Test {
    
    
    public static void main(String[] args) {
    
    
        VideoFactory videoFactory = new PythonVideoFactory();
        VideoFactory videoFactory2 = new JavaVideoFactory();
        VideoFactory videoFactory3 = new FEVideoFactory();
        Video video = videoFactory.getVideo();
        video.produce();
    }
}
==================================== 控制台输出 =======================================
Java。。。
  • UML类图
    ファクトリメソッドUMLクラス図
  • :3つのインスタンスファクトリが3つのクラスのインスタンスの生成に対応していることがわかります。テストテストクラスで使用するインスタンスは、取得するオブジェクトのファクトリインスタンスを見つけるだけです。
  • JDKソースコードでの使用例:java.util.Collection#iterator、ファクトリインターフェイスメソッド

抽象ファクトリ

  • 定義:抽象ファクトリパターンは1つを提供し创建一系列相关或相互依赖对象的接口、特定のクラスを指定する必要はありません
  • タイプ:作成
  • シナリオの使用
    • クライアント(アプリケーション層)は、製品クラスインスタンスの作成方法と実装方法の詳細に依存しません
    • 一連の関連する製品オブジェクト(同じ製品ファミリに属し、製品ファミリの概念については後で説明します)を一緒に使用して、多くの反復コードを必要とするオブジェクトを作成することを強調します
    • 製品クラスライブラリを提供すると、すべての製品が同じインターフェイスで表示されるため、クライアントは特定の実装に依存しません。
  • 利点
    • 特定の製品はアプリケーション層コードで分離されているため、作成の詳細を気にする必要はありません。
    • 一連の製品ファミリを統合して作成する
  • 短所
    • 作成される可能性のあるすべての製品セットを指定します。製品ファミリで新製品を拡張することは困難であり、抽象ファクトリのインターフェイスを変更する必要があります。
    • システムの抽象化と理解の難しさが増した
  • コーディング
/**
 * 定义文章抽象类和两个继承类
 */
public abstract class Article {
    
    
    public abstract void produce();
}
public class JavaArticle extends Article {
    
    
    @Override
    public void produce() {
    
    
        System.out.println("Java文章。。。");
    }
}
public class PythonArticle extends Article {
    
    
    @Override
    public void produce() {
    
    
        System.out.println("Python文章。。。");
    }
}
/**
 * 定义视频抽象类和两个继承类
 */
public abstract class Video {
    
    
    public abstract void produce();
}
public class JavaVideo extends Video {
    
    
    @Override
    public void produce() {
    
    
        System.out.println("Java。。。");
    }
}
public class PythonVideo extends Video {
    
    
    @Override
    public void produce() {
    
    
        System.out.println("Python。。。");
    }
}
/**
 * 
 */
public interface CourseFactory {
    
    
    Video getVideo();
    Article getArticle();
}
public class JavaCourseFactory implements CourseFactory {
    
    
    @Override
    public Video getVideo() {
    
    
        return new JavaVideo();
    }
    @Override
    public Article getArticle() {
    
    
        return new JavaArticle();
    }
}
public class PythonCourseFactory implements CourseFactory {
    
    
    @Override
    public Video getVideo() {
    
    
        return new PythonVideo();
    }
    @Override
    public Article getArticle() {
    
    
        return new PythonArticle();
    }
}
public class Test {
    
    
    public static void main(String[] args) {
    
    
        CourseFactory courseFactory = new JavaCourseFactory();
        Video video = courseFactory.getVideo();
        Article article = courseFactory.getArticle();
        video.produce();
        article.produce();
    }
}
==================================== 控制台输出 =======================================
Java视频。。。
Java文章。。。
  • UML类图
    抽象ファクトリUMLクラス図
  • :3つのインスタンスファクトリが3つのクラスのインスタンスの生成に対応していることがわかります。テストテストクラスで使用するインスタンスは、取得するオブジェクトのファクトリインスタンスを見つけるだけです。
  • JDKソースコードでの使用例:java.util.Collection#iterator、ファクトリインターフェイスメソッド

製品ファミリとは

  • アイコン
    製品ファミリアイコン
  • 説明
    • 各行は美的などの製品ファミリであり、正方形は美しい冷蔵庫を表し、円は美しいエアコンを表し、楕円形は美しい給湯器を表します。
    • 各列は製品レベルの構造です。たとえば、最初の行の円は美的エアコン、2番目の行の円はグリーのエアコン、3番目の行の円はハイアールのエアコンを表します。

おすすめ

転載: blog.csdn.net/qq_36221788/article/details/114444299