web-dev-qa-db-ja.com

ファサードのデザインパターンとは何ですか?

facadeは他の多くのクラスを含むクラスですか?

何がデザインパターンなのでしょうか?私にとっては、普通のクラスのようなものです。

このFacadeパターンを説明してもらえますか?

178
kevin

設計パターンは、繰り返し発生する問題を解決する一般的な方法です。すべてのデザインパターンのクラスは、通常のクラスです。重要なのは、それらがどのように構成され、どのように連携して特定の問題を最良の方法で解決するかです。

Facade設計パターンは、複雑なシステムへのインターフェースを簡素化します。これは通常、複雑なシステムのサブシステムを構成するすべてのクラスで構成されているためです。

Facadeは、システムの複雑な詳細からユーザーを保護し、simplified viewであるeasy to useを提供します。また、サブシステムの詳細からシステムを使用するコードをdecouplesし、後でシステムを簡単に変更できるようにします。

http://www.dofactory.com/Patterns/PatternFacade.aspx

http://www.blackwasp.co.uk/Facade.aspx

また、設計パターンを学習する際に重要なのは、特定の問題に適合するパターンを認識し、適切に使用できるようにすることです。パターンを誤用したり、パターンを知っているという理由だけでそれを何らかの問題に合わせようとすることは、非常に一般的なことです。デザインパターンを学習または使用する際には、これらの落とし穴に注意してください。

177

Wikipedia は、ファサードパターンの素晴らしい例です。

/* Complex parts */

class CPU {
    public void freeze() { ... }
    public void jump(long position) { ... }
    public void execute() { ... }
}

class Memory {
    public void load(long position, byte[] data) { ... }
}

class HardDrive {
    public byte[] read(long lba, int size) { ... }
}

/* Facade */

class ComputerFacade {
    private CPU processor;
    private Memory ram;
    private HardDrive hd;

    public ComputerFacade() {
        this.processor = new CPU();
        this.ram = new Memory();
        this.hd = new HardDrive();
    }

    public void start() {
        processor.freeze();
        ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE));
        processor.jump(BOOT_ADDRESS);
        processor.execute();
    }
}

/* Client */

class You {
    public static void main(String[] args) {
        ComputerFacade computer = new ComputerFacade();
        computer.start();
    }
}
90
egezer

前の回答で説明したように、それは消費クライアントにシンプルなインターフェースを提供します。たとえば、「watch ESPN」は目的の機能です。ただし、次のようないくつかの手順が必要です。

  1. 必要に応じてテレビの電源を入れます。
  2. 衛星/ケーブルの機能を確認してください。
  3. 必要に応じてESPNに切り替えます。

しかし、ファサードはこれを単純化し、クライアントに「ESPNの監視」機能を提供します。

40
Aravind

Facadeは、システムの複雑さを隠し、クライアントがシステムにアクセスできるクライアントへのインターフェースを提供します。

public class Inventory {
public String checkInventory(String OrderId) {
    return "Inventory checked";
}
}

public class Payment {
public String deductPayment(String orderID) {
    return "Payment deducted successfully";
}
}


public class OrderFacade {
private Payment pymt = new Payment();
private Inventory inventry = new Inventory();

public void placeOrder(String orderId) {
    String step1 = inventry.checkInventory(orderId);
    String step2 = pymt.deductPayment(orderId);
    System.out
            .println("Following steps completed:" + step1
                    + " & " + step2);
   }
}

public class Client {
       public static void main(String args[]){
         OrderFacade orderFacade = new OrderFacade();
         orderFacade.placeOrder("OR123456");
         System.out.println("Order processing completed");
       }
  }
28
KaviK

短く簡単な説明:

  • ファサードパターンは、サブシステム内の一連のインターフェイスへの統合インターフェイスを提供します。
  • Facadeは、サブシステムを使いやすくする高レベルのインターフェースを定義します。

ファサードを使用した場合と使用しない場合のシナリオを理解してください。
accout1からaccount2に送金する場合、呼び出される2つのサブシステムは、account1から引き出してaccount2に入金します。

with and without facade

15
Arun Raaj

ファサードは、他の多くのクラスを含むクラスとして記述すべきではありません。実際には、このクラスへのインターフェースであり、クラスの使用を容易にする必要があります。そうしないと、ファサードクラスは役に立たなくなります。

10
llMll

クエリについて:

Facadeは他の多くのクラスを含むクラスですか?

はい。これは、アプリケーション内の多くのサブシステムのラッパーです。

何がデザインパターンなのでしょうか?私にとっては、普通のクラスのようなものです

デザインパターンもすべて通常のクラスです。 @ nmesh Kondolikarは、このクエリに正しく回答しました。

このファサードについて説明してもらえますか、私はパターンを設計するのが初めてです。

GoFによれば、Facadeの設計パターンは次のように定義されます:

サブシステム内のインターフェイスのセットに統合インターフェイスを提供します。 Facade Patternは、サブシステムを使いやすくする高レベルのインターフェイスを定義します

Facade パターンは通常、次の場合に使用されます。

  1. 複雑なシステムにアクセスするには、シンプルなインターフェースが必要です。
  2. サブシステムの抽象化と実装は密結合されています。
  3. 階層化ソフトウェアの各レベルへのエントリポイントが必要です。
  4. システムは非常に複雑であるか、理解するのが困難です。

cleartrip websiteの実際のWordの例を見てみましょう。

このウェブサイトは予約するオプションを提供します

  1. フライト
  2. ホテル
  3. フライト+ホテル

コードスニペット:

import Java.util.*;

public class TravelFacade{
    FlightBooking flightBooking;
    TrainBooking trainBooking;
    HotelBooking hotelBooking;

    enum BookingType {
        Flight,Train,Hotel,Flight_And_Hotel,Train_And_Hotel;
    }; 

    public TravelFacade(){
        flightBooking = new FlightBooking();
        trainBooking = new TrainBooking();
        hotelBooking = new HotelBooking();        
    }
    public void book(BookingType type, BookingInfo info){
        switch(type){
            case Flight:
                // book flight;
                flightBooking.bookFlight(info);
                return;
            case Hotel:
                // book hotel;
                hotelBooking.bookHotel(info);
                return;
            case Train:
                // book Train;
                trainBooking.bookTrain(info);
                return;
            case Flight_And_Hotel:
                // book Flight and Hotel
                flightBooking.bookFlight(info);
                hotelBooking.bookHotel(info);
                return;
             case Train_And_Hotel:
                // book Train and Hotel
                trainBooking.bookTrain(info);
                hotelBooking.bookHotel(info);
                return;                
        }
    }
}
class BookingInfo{
    String source;
    String destination;
    Date    fromDate;
    Date     toDate;
    List<PersonInfo> list;
}
class PersonInfo{
    String name;
    int       age;
    Address address;
}
class Address{

}
class FlightBooking{
    public FlightBooking(){

    }
    public void bookFlight(BookingInfo info){

    }
}
class HotelBooking{
    public HotelBooking(){

    }
    public void bookHotel(BookingInfo info){

    }
}
class TrainBooking{
    public TrainBooking(){

    }
    public void bookTrain(BookingInfo info){

    }
}

説明:

  1. FlightBooking, TrainBooking and HotelBookingは、大規模システムの異なるサブシステムです:TravelFacade

  2. TravelFacadeは、以下のオプションのいずれかを予約するためのシンプルなインターフェースを提供します

    Flight Booking
    Train Booking 
    Hotel Booking
    Flight + Hotel booking 
    Train + Hotel booking
    
  3. travelFacadeのブックAPIは、サブシステムの以下のAPIを内部的に呼び出します

    flightBooking.bookFlight
    trainBooking.bookTrain(info);
    hotelBooking.bookHotel(info);
    
  4. このように、TravelFacadeは、サブシステムAPIを公開せずに、よりシンプルで簡単なAPIを提供します。

主なポイント:( journaldev from Pankaj Kumarの記事)

  1. ファサードパターンは、クライアントアプリケーションのhelperに似ています
  2. ファサードパターンは、開発の任意の時点で適用できます。通常はインターフェイスの数が増えてシステムが完成するときx
  3. サブシステムインターフェイスはFacadeを認識せず、それらはFacadeインターフェイスの参照を持たない
  4. 同様の種類のインターフェースにファサードパターンを適用する、その目的は、複数のインターフェースではなく単一のインターフェースを提供することです同様の仕事

よりよく理解するには、 sourcemaking の記事もご覧ください。

7
Ravindra babu

ファサードパターンのもう1つの用途は、チームの学習曲線を減らすことです。例を挙げましょう。

Excelが提供するCOMオブジェクトモデルを使用して、アプリケーションがMS Excelと対話する必要があると仮定します。チームメンバーの1人がすべてのExcel APIを知っており、その上にFacadeを作成します。これにより、アプリケーションのすべての基本的なシナリオが満たされます。チームの他のメンバーがExcel APIの学習に時間を費やす必要はありません。チームは、シナリオの実行に関係する内部構造やすべてのMS Excelオブジェクトを知らなくてもファサードを使用できます。それは素晴らしいことではありませんか?

したがって、複雑なサブシステムの上に簡素化され統合されたインターフェイスを提供します。

6
Anand Patel

ファサードパターンは、よりシンプルなインターフェイスを生成するために、他の多くのインターフェイスのラッパーです。

設計パターンは、繰り返し発生する問題を解決し、一般的にコードを簡素化するので便利です。同じパターンを使用することに同意する開発者のチームでは、お互いのコードを保守する際の効率と理解が向上します。

他のパターンについて読んでみてください:

ファサードパターン: http://www.dofactory.com/Patterns/PatternFacade.aspx#_self1

またはより一般的に: http://www.dofactory.com/Patterns/Patterns.aspx

6
Aim Kai

ファサードは、ほとんどが呼び出される単純化された関数を公開し、実装は、クライアントが対処しなければならない複雑さを隠します。一般に、実装では複数のパッケージ、クラス、および関数が使用されます。よく書かれたファサードにより、他のクラスに直接アクセスすることはまれです。たとえば、ATMにアクセスして、いくらかの金額を引き出した場合。 ATMは、所有銀行に直行するのか、外部銀行のネゴシエートされたネットワークを経由するのかを隠します。 ATMは、複数のデバイスとサブシステムを使用するファサードのように機能し、クライアントとして直接対処する必要はありません。

5
ManojPatra

Facadeでは、単一のインターフェイスオブジェクト内に複雑なサブシステムをカプセル化する方法について説明しています。これにより、サブシステムをうまく活用するために必要な学習曲線が削減されます。また、潜在的に多くのクライアントからサブシステムを切り離すことを促進します。一方、Facadeがサブシステムの唯一のアクセスポイントである場合、「パワーユーザー」が必要とする機能と柔軟性が制限されます。

ソース: https://sourcemaking.com/design_patterns/facade

4
user6102894

パターンの非常に良い実例があります-車のスターターエンジン

ドライバーとして、キーをオンにするだけで車が始動します。可能な限りシンプル。舞台裏では、他の多くの車のシステム(バッテリー、エンジン、燃料など)が関与しており、車が正常に始動しますが、スターターの後ろに隠れています。

ご覧のとおり、自動車のスターターはファサードです。他のすべての自動車システムの複雑さを心配することなく、使いやすいインターフェースを提供します。

要約しましょう:

Facadeパターンは、大規模なコードブロックまたはAPIの複雑さを簡素化して隠し、よりクリーンで理解しやすく使いやすいインターフェースを提供します。

4
Jordan Enev

ファサードは、ツールキットと完全なアプリケーションの間にあるレベルの機能を備えたクラスであり、パッケージまたはサブシステム内のクラスの使用を簡素化します。 Facadeパターンの目的は、サブシステムを使いやすくするインターフェースを提供することです。 -から抽出 book C#のデザインパターン。

4
Sean Hunter

ファサードの別の例:アプリケーションがデータベースに接続し、UIに結果を表示するとします。データベースを使用して、またはモックオブジェクトを使用して実行中のように、ファサードを使用してアプリケーションを構成可能にすることができます。したがって、ファサードクラスに対してすべてのデータベース呼び出しを行います。このクラスでは、アプリの構成を読み取り、dbクエリを起動するか、モックオブジェクトを返すかを決定します。これにより、dbが使用できない場合にアプリケーションがdbに依存しなくなります。

4
aishu

設計パターンは、ソフトウェア設計の特定のコンテキスト内で一般的に発生する問題に対する一般的な再利用可能なソリューションです。

Facadeデザインパターンは、クラスまたはエンティティ間の関係を作成する方法を定義する構造パターンです。ファサードデザインパターンは、より複雑なサブシステムへの簡素化されたインターフェイスを定義するために使用されます。

ファサードパターンは、相互に依存する多数のクラス、または複数のメソッドの使用を必要とするクラス、特に使用が複雑または理解が難しいクラスで作業する場合に理想的です。ファサードクラスは、理解しやすく使いやすいメンバーのセットを含む「ラッパー」です。これらのメンバーは、ファサードユーザーに代わってサブシステムにアクセスし、実装の詳細を隠します。

ファサードのデザインパターンは、ソースコードが利用できないか、既存のインターフェイスが広く使用されているために設計が不十分だがリファクタリングできないサブシステムをラップする場合に特に役立ちます。場合によっては、異なる目的のために機能のサブセットを提供するために複数のファサードを実装することを決定することがあります。

ファサードパターンの使用例の1つは、Webサイトをビジネスアプリケーションと統合することです。既存のソフトウェアには、特定の方法でアクセスする必要がある大量のビジネスロジックが含まれている場合があります。 Webサイトでは、このビジネスロジックへの制限付きアクセスのみが必要な場合があります。たとえば、Webサイトでは、販売中の商品が限られた在庫レベルに達しているかどうかを表示する必要がある場合があります。ファサードクラスのIsLowStockメソッドは、これを示すブール値を返すことができます。この方法では、現在の物理的な在庫、入荷在庫、割り当てられたアイテム、および各アイテムの低い在庫レベルの処理の複雑さを隠しています。

3
Program-Me-Rev

複数のメソッドを呼び出すラッパーを作成するだけです。メソッドx()およびy()を持つAクラスと、メソッドk()およびz()を持つBクラスがあります。 x、y、zを一度に呼び出して、Facadeパターンを使用してそれを行うには、Facadeクラスを作成し、メソッドを作成してxyz()とします。各メソッド(x、yおよびz)を個別に呼び出す代わりに、それらのメソッドを呼び出すファサードクラスのラッパーメソッド(xyz())を呼び出すだけです。

同様のパターンはリポジトリですが、主にデータアクセスレイヤー用です。

2
Jeff Schreib

すべての設計パターンは、特定のアプリケーションに適した何らかの方法で配置されたクラスです。ファサードパターンの目的は、1つまたは複数の操作の複雑さを隠すことです。 http://preciselyconcise.com/design_patterns/facade.php からサンプルを見て、ファサードパターンを学ぶことができます。

2
Sai Sunder

ファサードデザインパターンは、構造デザインパターンの下にあります。要するに、ファサードとは外観を意味します。これは、Facadeのデザインパターンで何かを非表示にし、実際にクライアントが必要とするものだけを表示することを意味します。詳細については、以下のブログをご覧ください: http://www.sharepointcafe.net/2017/03/facade-design-pattern-in-aspdotnet.html

1
user1694660

基本的には単一ウィンドウのクリアランスシステムです。別のクラスの特定のメソッドに委任する作業を割り当てます。

1
Saurabh

ファサードパターンは、サブシステムインターフェイスグループへの統合インターフェイスを提供します。ファサードは、サブシステムとの作業を簡素化する高レベルのインターフェースを定義します。

1
Taras Melnyk