通常、オブジェクトを作成するときは、キーワードnewを使用して達成します。例:Class A = new A()。
場合によっては、作成するオブジェクトに、構成ファイルのチェック、データベーステーブルのチェック、メンバーオブジェクトの初期化など、一連の複雑な初期化操作が必要になります。これらのロジックをコンストラクターに配置すると、コードの読みやすさに大きな影響があります。 。オブジェクトの作成を担当するクラスを定義することもできます。このようなクラスはファクトリクラスです。このアプローチはファクトリパターンです。ファクトリパターンは、複雑なオブジェクトを生成する必要がある場所ならどこでも使用できます。
工場パターンには、単純な工場(23の設計パターンには含まれない)、工場の方法、および抽象的な工場が含まれます。
解決した問題
クライアントは、呼び出し時にインスタンス化するクラスを判断したくないか、インスタンス化プロセスが複雑すぎます。
ファクトリモデルでは、特定の実装クラスの作成プロセスはクライアントに対して透過的であり、クライアントはインスタンス化するクラスを決定しませんが、インスタンス化のために「ファクトリ」に渡されます。
シンプルな工場
▐ 構造
オブジェクトを作成するためのインターフェイスを定義し、そのサブクラスにインスタンス化するファクトリクラスを決定させます。
抽象クラスまたはインターフェース:作成する製品オブジェクトのインターフェースを定義します。
特定の実現:統一された親カテゴリを持つ特定のタイプの製品。
製品ファクトリ:製品オブジェクトの作成を担当します。ファクトリーモデルは、「特定の製品実装クラスを作成する」という変更されたコードを「製品を使用する」という変更されていないコードから分離する開閉の原則も具体化しており、新しい製品を追加する場合は、ファクトリの実装を拡張するだけで済みます。それでおしまい。
▐ 使用
さまざまなブランドのキーボードを作成する
public interface Keyboard {
void print();
void input(Context context);
}
class HPKeyboard implements Keyboard {
@Override
public void print() {
//...输出逻辑;
}
@Override
public void input(Context context) {
//...输入逻辑;
}
}
class DellKeyboard implements Keyboard {
@Override
public void print() {
//...输出逻辑;
}
@Override
public void input(Context context) {
//...输入逻辑;
}
}
class LenovoKeyboard implements Keyboard {
@Override
public void print() {
//...输出逻辑;
}
@Override
public void input(Context context) {
//...输入逻辑;
}
}
/**
* 工厂
*/
public class KeyboardFactory {
public Keyboard getInstance(int brand) {
if(BrandEnum.HP.getCode() == brand){
return new HPKeyboard();
} else if(BrandEnum.LENOVO.getCode() == brand){
return new LenovoKeyboard();
} else if(BrandEnum.DELL.getCode() == brand){
return new DellKeyboard();
}
return null;
}
public static void main(String[] args) {
KeyboardFactory keyboardFactory = new KeyboardFactory();
Keyboard lenovoKeyboard = KeyboardFactory.getInstance(BrandEnum.LENOVO.getCode());
//...
}
}
▐ 欠陥
上記のファクトリ実装は、インターフェイスまたは抽象クラスではなく、具象クラスKeyboardFactoryです。getInstance()メソッドは、if-elseを使用して、具象キーボードインスタンスを作成および返します。新しいキーボードサブクラスが追加されると、キーボードファクトリ作成メソッドは新しいif-elseを追加します。このアプローチはスケーラビリティが低く、開閉の原則に違反し、読みやすさにも影響します。したがって、このメソッドは、ビジネスが単純で、ファクトリクラスが頻繁に変更されない状況で使用されます。
工場方式
上記の「if-elseの増加」の問題を解決するために、対応するファクトリサブクラスをキーボードサブクラスごとに確立でき、これらのファクトリサブクラスは同じ抽象ファクトリインターフェイスを実装します。このように、さまざまなブランドのキーボードを作成するには、さまざまなファクトリサブクラスを実装するだけで済みます。新しいブランドが追加されると、新しいコンクリートファクトリはクラスを変更せずに抽象ファクトリを継承します。
▐ 構造
抽象ファクトリ:ファクトリメソッドのインターフェイスを宣言します。
特定の製品ファクトリ:ファクトリメソッドのインターフェイスを実装し、製品オブジェクトの作成を担当します。
製品抽象クラスまたはインターフェース:factoryメソッドによって作成された製品オブジェクトのインターフェースを定義します。
特定の製品の実現:統一された親カテゴリを持つ特定のタイプの製品。
▐ 使用
public interface IKeyboardFactory {
Keyboard getInstance();
}
public class HPKeyboardFactory implements IKeyboardFactory {
@Override
public Keyboard getInstance(){
return new HPKeyboard();
}
}
public class LenovoFactory implements IKeyboardFactory {
@Override
public Keyboard getInstance(){
return new LenovoKeyboard();
}
}
public class DellKeyboardFactory implements IKeyboardFactory {
@Override
public Keyboard getInstance(){
return new DellKeyboard();
}
}
▐ 欠点
各ブランドはファクトリサブクラスに対応しています。特定のキーボードオブジェクトを作成するときは、さまざまなファクトリサブクラスをインスタンス化します。しかし、ビジネスにますます多くのサブカテゴリが含まれる場合、各サブカテゴリはファクトリカテゴリに対応しますか?これにより、システム内のクラスの数が2倍になり、コードが複雑になります。
抽象工場
工場実装サブカテゴリの数を減らすために、各製品に工場カテゴリを割り当てる必要はありません。製品をグループ化できます。各グループの異なる製品は、同じ工場カテゴリの異なる方法で作成されます。
たとえば、キーボードとホストの2つの製品を同じグループにグループ化することができます-コンピュータ、および異なるブランドのコンピュータは異なるメーカーによって作成されます。
製品カテゴリがグループ化され、グループ内のさまざまな製品が同じファクトリカテゴリのさまざまな方法で実装されるこの設計パターンと同様に、これは抽象的なファクトリパターンです。
抽象ファクトリは、次の状況に適しています。
1.システムがその製品の作成、組み合わせ、および表示から独立している
場合; 2。システムが複数の製品シリーズの1つによって構成されている場合;
3。ジョイント用の一連の関連製品オブジェクトの設計を強調する場合使用時;
4。製品クラスライブラリを提供するが、実装ではなくインターフェイスのみを表示したい場合。
▐ 構造
抽象ファクトリ:抽象製品オブジェクトを作成するための操作インターフェースを宣言します。
特定の製品ファクトリ:抽象ファクトリのインターフェイスを実装し、製品オブジェクトの作成を担当します。
製品抽象クラスまたはインターフェース:製品オブジェクトのクラスのインターフェースを定義します。
特定の製品の実現:対応する特定の工場によって作成される製品オブジェクトを定義します。
▐ 使用
public interface Keyboard {
void print();
}
public class DellKeyboard implements Keyboard {
@Override
public void print() {
//...dell...dell;
}
}
public class HPKeyboard implements Keyboard {
@Override
public void print() {
//...HP...HP;
}
}
public interface Monitor {
void play();
}
public class DellMonitor implements Monitor {
@Override
public void play() {
//...dell...dell;
}
}
public class HPMonitor implements Monitor {
@Override
public void play() {
//...HP...HP;
}
}
public interface MainFrame {
void run();
}
public class DellMainFrame implements MainFrame {
@Override
public void run() {
//...dell...dell;
}
}
public class HPMainFrame implements MainFrame {
@Override
public void run() {
//...HP...HP;
}
}
//工厂类。工厂分为Dell工厂和HP工厂,各自负责品牌内产品的创建
public interface IFactory {
MainFrame createMainFrame();
Monitor createMainFrame();
Keyboard createKeyboard();
}
public class DellFactory implements IFactory {
@Override
public MainFrame createMainFrame(){
MainFrame mainFrame = new DellMainFrame();
//...造一个Dell主机;
return mainFrame;
}
@Override
public Monitor createMonitor(){
Monitor monitor = new DellMonitor();
//...造一个Dell显示器;
return monitor;
}
@Override
public Keyboard createKeyboard(){
Keyboard keyboard = new DellKeyboard();
//...造一个Dell键盘;
return Keyboard;
}
}
public class HPFactory implements IFactory {
@Override
public MainFrame createMainFrame(){
MainFrame mainFrame = new HPMainFrame();
//...造一个HP主机;
return mainFrame;
}
@Override
public Monitor createMonitor(){
Monitor monitor = new HPMonitor();
//...造一个HP显示器;
return monitor;
}
@Override
public Keyboard createKeyboard(){
Keyboard keyboard = new HPKeyboard();
//...造一个HP键盘;
return Keyboard;
}
}
//客户端代码。实例化不同的工厂子类,可以通过不同的创建方法创建不同的产品
public class Main {
public static void main(String[] args) {
IFactory dellFactory = new DellFactory();
IFactory HPFactory = new HPFactory();
//创建戴尔键盘
Keyboard dellKeyboard = dellFactory.createKeyboard();
//...
}
}
▐長所 と短所
グループの追加は非常に簡単です。たとえば、Lenovoグループを追加するには、Lenovoファクトリと特定の製品実装クラスを作成するだけで済みます。グループ内の製品を拡張することは非常に困難です。マウスを追加するには、抽象的なマウスインターフェイスを作成するだけでなく、特定の実装(DellMouse、HPMouse)を増やし、各ファクトリでマウスを作成する方法を定義する必要があります。
▐ まとめ
単純なファクトリ:一意のファクトリクラス、製品抽象クラス、ファクトリクラスの作成メソッドは、入力パラメータに基づいて特定の製品オブジェクトを判断および作成します。
ファクトリメソッド:複数のファクトリクラス、1つの製品抽象クラスは、多態性を使用してさまざまな製品オブジェクトを作成し、他の多くの判断を回避します。
抽象ファクトリ:複数のファクトリクラス、複数の製品抽象クラス、製品サブカテゴリのグループ化、同じファクトリ実装クラスは、同じグループに異なる製品を作成し、ファクトリサブカテゴリの数を減らします。
ファクトリモデルは、次の状況で検討できます。
コーディング時にどのような種類のインスタンスを作成する必要があるかを予測することはできません。
システムは、製品クラスインスタンスが作成、結合、および表現される方法の詳細に依存するべきではありません。
つまり、ファクトリパターンは、同じインターフェイスで定義された複雑なパラメータと初期化ステップを使用して、さまざまなオブジェクトの作成を容易にすることです。ファクトリパターンは通常、複雑なオブジェクトを作成するために使用されます。工場出荷時のパターンを使用せずに、単にnewを使用して成功する単純なオブジェクトを作成します。そうしないと、システムの複雑さが増します。
また、オブジェクトのパラメータが固定されていない場合は、ビルダーモードを使用することをお勧めします。
追記
実際のプロジェクトでは、SpringのInitializingBeanインターフェースと組み合わせて、@ Autowiredアノテーションを使用してファクトリをエレガントに実装できます。
タオ部門技術部門-業界技術チーム-人材の採用
私たちは、タオイスト業界のeコマースビジネスの成長と革新を担当するアリババタオイスト業界の技術チームです。アパレル、FMCG、住宅改修、電力消費など、数十の業界の急速な発展をサポートしています。毎日数千万のユーザーにサービスを提供し、数千のユーザーを生み出しています。 1億GMV。ここでは、Taobao業界全体のコアビジネスと技術システムに触れ、複数のTaobao Tmall業界に力を与え、革新的なビジネスを迅速に育成できます。ここでは、業界の商業化と流通のシナリオをさらに深く掘り下げて、業界を活性化することもできます。さまざまな生態学的役割がeコマースビジネスに新たな成長をもたらします。
募集ポジション:Java開発
あなたが興味を持っている場合は、にあなたの履歴書を送ってください[email protected]歓迎、するピックアップ〜アップ
✿さらに 読む
著者| Fang Hui(Huaixing)
編集|オレンジ
生産|アリババの新しい小売技術