In che modo il modello di facciata è diverso dagli strati di astrazione?

7

Ho appena letto del modello di facciata e ho trovato questo esempio in cui un client (utente di un computer) richiama un metodo startComputer() che chiama tutte le cose complesse:

Fonte: 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 Computer {
    private CPU cpu;
    private Memory memory;
    private HardDrive hardDrive;

    public Computer() {
        this.cpu = new CPU();
        this.memory = new Memory();
        this.hardDrive = new HardDrive();
    }

    public void startComputer() {
        cpu.freeze();
        memory.load(BOOT_ADDRESS, hardDrive.read(BOOT_SECTOR, SECTOR_SIZE));
        cpu.jump(BOOT_ADDRESS);
        cpu.execute();
    }
}

/* Client */

class You {
    public static void main(String[] args) {
        Computer facade = new Computer();
        facade.startComputer();
    }
}

Qui possiamo vedere la classe client (tu) che crea una nuova facciata, chiamando il metodo startComputer() . Questo metodo crea un'istanza di diversi oggetti e invoca i loro metodi, incapsulandolo all'interno della classe facade dove 'glues it together' .

Domanda 1:

Ma com'è esattamente diverso dai livelli di astrazione?

Ieri ho eseguito la funzionalità di accesso per un'applicazione web in cui un doLogin($username, $password) ha incapsulato un metodo 'complex' di livello inferiore chiama le informazioni di accesso aggiornate sull'utente, imposta le sessioni per accedere e ha istanziato diversi oggetti ecc. per eseguire questa operazione lavoro.

Questo livello chiamerebbe anche un altro livello ancora più basso che avrebbe a che fare con operazioni di tipo CRUD come il controllo dello stato di attivazione, dell'esistenza dell'account e altre cose come l'elaborazione di stringhe tramite algoritmi di hashing. Questo metodo (a livello di modello, guarda 'panoramica dei livelli' sotto) restituirebbe un array con una chiave 'success' o una chiave 'error_message' , agendo come un booleano di ordinamenti per il livello che lo chiama .

Questo è ciò che capisco è noto come 'abstraction layers' , che nasconde le procedure complesse dall'architettura di livello superiore, ma quando leggo del modello di facciata sembra che lo stia usando da sempre?

Domanda 2:

Il mio approccio all'astrazione del meccanismo di accesso sarebbe una cattiva scelta in un'architettura MVC? (in caso contrario, si prega di fornire esempi perché)

Considerato dovrebbe essere molto facile decidere dove andrà il risultato finale (HTML, AJAX, ecc.), non sarebbe una scelta saggia per evitare un sacco di IF dato che questo può essere affrontato su un livello controller ?

Panoramica dei livelli:

Livello controller: $model->doLogin(POST VARIABLES HERE)

Livello del modello: (si tratta di una facciata?) Imposta sessioni, aggiorna le informazioni di accesso nel database ecc., chiama i componenti indipendenti per informazioni: $user_id = $user->getId(); e $session->sessionExists();

Livello di classe indipendente: ogni classe su questo livello è indipendente e ha un accoppiamento minimo o nullo. Dopo tutto, perché dovrebbe? È il lavoro di cui sopra per creare l'applicazione e prestare un'API per controllarla.

Domanda 3:

Il pattern di facciata è utilizzato solo per instradare le chiamate alle sottoclassi in un modulo simile a API, o forse solo più comunemente?

Con questo intendo: Oggetto A crea un'istanza dell'oggetto B e presta un metodo per controllare i metodi dell'oggetto B attraverso un metodo a sé stante:

<?php

class A {
    private $_objectB;

    public function __construct()
    {
        $this->_objectB = new B();
    }

    public function callMethodB()
    {
        $this->_objectB->methodB();
    }
}

class B {
    public function methodB()
    {
        die('Wuhu!');
    }
}

// --------------------------
$objectA->callMethodB(); // Wuhu!

invece di:

$objectA->objectB->methodB(); // Wuhu!
    
posta Seralize 29.11.2011 - 14:16
fonte

2 risposte

9

La relazione tra i due: Il modello di facciata è un sottoinsieme di "strati di astrazione". Una facciata è un ulteriore livello di astrazione. Non tutte le astrazioni sono Facciate.

In particolare, una facciata è dove offriamo un'interfaccia semplificata per un'API complessa. A volte stiamo avvolgendo numerose classi complesse in una semplice; a volte stiamo semplicemente prendendo una classe con un'API complessa e semplificandola per il codice chiamante.

Se stai semplicemente inoltrando una chiamata a un'altra classe con la stessa interfaccia, è più esattamente la sequenza Proxy . Questo è un altro tipo di livello di astrazione.

È una buona idea astrarre il log in un pattern MVC? Sì (la maggior parte dei framework MVC farà questo per te). Ma se dovresti astrarlo usando un proxy o una facciata dipende molto dall'API di accesso.

    
risposta data 29.11.2011 - 14:44
fonte
1

La stai interpretando totalmente nel modo sbagliato. Per riassumere in una riga "Un modello di facciata fornisce un'interfaccia semplificata in cui possiamo utilizzare le funzionalità di un sottosistema complesso". Il caso d'uso del modello di facciata è quello di fornire un accesso ai metodi di basso livello sottostanti di un servizio / pacchetto / componente complesso ecc.

Le seguenti cose non vengono nel caso d'uso della facciata:

  1. Un'astrazione per i processi (Questa potrebbe essere una parte, ma questo non dovrebbe essere l'unico scopo)
  2. Incapsula i processi in un unico processo

La facciata è usata solo per fornire un'implementazione concreta per tutti i metodi di basso livello

Un modello di facciata dovrebbe generalmente essere usato quando stiamo progettando un pacchetto complesso che va in profondità in sottosistemi e complessità. Una facciata è solo un accessorio per i metodod di livello lopw sottostante di un servizio / pacchetto / componente complesso ecc.

Esempio:

Passaggio 1

Crea un'interfaccia.

Shape.java :

public interface Shape {
   void draw();
}

Passaggio 2

Crea classi concrete che implementano la stessa interfaccia.

Rectangle.java

public class Rectangle implements Shape {

   @Override
   public void draw() {
      System.out.println("Rectangle::draw()");
   }
}

Square.java

public class Square implements Shape {

   @Override
   public void draw() {
      System.out.println("Square::draw()");
   }
}

Circle.java

public class Circle implements Shape {

   @Override
   public void draw() {
      System.out.println("Circle::draw()");
   }
}

Passaggio 3

Crea una classe di facciata.

ShapeMaker.java

public class ShapeMaker {
   private Shape circle;
   private Shape rectangle;
   private Shape square;

   public ShapeMaker() {
      circle = new Circle();
      rectangle = new Rectangle();
      square = new Square();
   }

   public void drawCircle(){
      circle.draw();
   }
   public void drawRectangle(){
      rectangle.draw();
   }
   public void drawSquare(){
      square.draw();
   }
}

Passaggio 4

Usa la facciata per disegnare vari tipi di forme.

FacadePatternDemo.java

public class FacadePatternDemo {
   public static void main(String[] args) {
      ShapeMaker shapeMaker = new ShapeMaker();

      shapeMaker.drawCircle();
      shapeMaker.drawRectangle();
      shapeMaker.drawSquare();      
   }
}

Passaggio 5

Verifica l'output.

Circle::draw()
Rectangle::draw()
Square::draw()

This pattern involves a single class which provides simplified methods required by client and delegates calls to methods of existing system classes.

    
risposta data 12.03.2015 - 10:56
fonte

Leggi altre domande sui tag