Avatar billede Smorkongen Nybegynder
29. december 2011 - 16:47 Der er 5 kommentarer og
1 løsning

Patterns oop

Hvad gør/hjælper et facade pattern med ?
Avatar billede DeeDawg Nybegynder
29. december 2011 - 21:35 #1
Egentlig ikke så meget. Når vi taler om patterns her, så er det faktisk bare navne, for metoder og måder at gøre tingene på, som vi betegner som almen praksis.

Facade pattern er betegnelsen for en klasse, som er designet til at være så brugervenlig som overhovedet muligt. Dvs. at alle de opgaver, som klassen godt selv kan udføre, bliver udført af klassen.

På den måde slipper brugeren af klassen for, at skulle skrive 500 linjer kode, for at få det ønskede resultat. Jeg giver dig herunder 2 eksempler, som viser dig hvad der menes i praksis.


Vores klasse (uden brug af facade pattern):

<?php
    class UdskrivNoget
    {
        public $navn, $alder, $adresse;
       
        public function definerNavn($navn){
            $this->navn = $navn;
        }
       
        public function definerAlder($alder){
            $this->alder = $alder;
        }
       
        public function definerAdresse($adresse){
            $this->adresse = $adresse;
        }
       
        public function udskrivResultat(){
            echo "Hej mit navn er ".$this->navn."! Jeg er ".$this->alder." år gammel og bor på ".$this->adresse.".";
        }
    }
   
    $UN = new UdskrivNoget();
    $UN->definerNavn("Anders Andersen");
    $UN->definerAlder(20);
    $UN->definerAdresse("Æblevej 1, 2100 København");
    $UN->udskrivResultat();
?>

Som du kan se, er det her en meget upraktisk klasse. Hvordan kan vi løse det, uden at skulle omskrive hele klassen? Tjah, vi kan jo prøve at gøre den lidt mere enkel at benytte. :)


Vores klasse (med brug af facade pattern):

<?php
    class UdskrivNoget
    {
        public $navn, $alder, $adresse;
       
        public function __construct($navn, $alder, $adresse){
            $this->definerNavn($navn);
            $this->definerAlder($alder);
            $this->definerAdresse($adresse);
           
            $this->udskrivResultat();
        }
       
        public function definerNavn($navn){
            $this->navn = $navn;
        }
       
        public function definerAlder($alder){
            $this->alder = $alder;
        }
       
        public function definerAdresse($adresse){
            $this->adresse = $adresse;
        }
       
        public function udskrivResultat(){
            echo "Hej mit navn er ".$this->navn."! Jeg er ".$this->alder." år gammel og bor på ".$this->adresse.".";
        }
    }
   
    $UN = new UdskrivNoget("Anders Andersen", 20, "Æblevej 1, 2100 København");
?>

Som du kan se, så er det den samme klasse. Den udfører også den samme opgave, men vi sørger for at alle de her funktioner bliver kaldt internt, og derfor skåner brugeren for det.

Håber det hjælper dig til at forstå. ;)
Avatar billede JensPeterSvensson Nybegynder
30. december 2011 - 12:55 #2
Et facade pattern.

Er essentielt set bare en væg (interface) mellem to verdener, den indvendige og den udvendige.

Det betyder at dem der implementere den indvendige verdenen ikke er bundet af brugerne fra den udvendige verden.

Og dem der implementerer den udvendige kun skal vide hvordan facaden ser ud.

Facaden i sig selv er en klasse.


PS. Det som foregående poster beskriver, er jeg rimelig sikker på ikke kan kaldes et eksempel på facade pattern.
Avatar billede DeeDawg Nybegynder
30. december 2011 - 16:52 #3
Sjovt, når du rent faktisk skriver præcis det samme som jeg gør. :)

Vil egentlig gerne høre mere om, hvad du mener er forkert i de eksempler jeg gav?
Hvordan mener du, at de ikke viser at brugeren kun ser facaden/toppen af isbjerget/kald det hvad du vil?

Fordi, jeg kan ikke følge dig. :)
Avatar billede JensPeterSvensson Nybegynder
31. december 2011 - 10:36 #4
Koden brugeren ikke behøver kende, (tegnings biblioteket):


<?php

class Canvas{
  private $gdimg;
  private $width;
  private $height;

  public function __construct($width, $height){
    $this->width = $width;
    $this->height = $height;
    $this->gdimg = imagecreate($width, $height);
  }

  public function getImage(){
    return $this->gdimg;
  }

  public function floodfill($color, $x, $y){
    imagefill($this->gdimg, $x, $y, $color->getColor());
  }

  public function getHeight(){
    return $this->height;
  }

  public function getWidth(){
    return $this->width;
  }
}

Class Color{
  private $color;
  public function  __construct($canvas, $red, $green, $blue){
    $this->color = imagecolorallocate($canvas->getImage(), $red, $green, $blue);
  }

  public function getColor(){
    return $this->color;
  }
}

Class DrawRelatives{
  public function fillRect($canvas, $x, $w, $y, $h, $color){
    $x = floor($canvas->getWidth()*$x);
    $w = $x + floor($canvas->getWidth()*$w);
    $y = floor($canvas->getHeight()*$y);
    $h = $y + floor($canvas->getHeight()*$h);
    imagefilledrectangle($canvas->getImage(), $x,$y,$w,$h, $color->getColor());
  }
}
?>


Facaden der kan tegne flag (kun det danske):

<?php
include_once dirname(__FILE__).'/canvas.php';
class Flags{

  public function danish($s){
    $w = 37*$s;
    $h = 28*$s;
    $c = new Canvas($w, $h);
    $white = new Color($c, 255,255,255);
    $red = new Color($c, 255,0,0);
    $c->floodfill($red, 0, 0);
    $relatives = new DrawRelatives();
    $relatives->fillRect($c, (12*$s)/$w,(4*$s)/$w, 0, 1, $white);
    $relatives->fillRect($c, 0, 1, (12*$s)/$h, (4*$s)/$h, $white);
    header('Content-Type: image/png');
    $im = $c->getImage();
    imagepng($im);
    imagedestroy($im);
  }
}
?>


Brugerens kode:

<?php
include 'flags.php';
$f = new Flags();
$f->danish(4);
?>


Fordelen er at brugeren af flags facaden ikke behøver kende det underliggende tegningsbibliotek, hans kode er kun afhængig af facadens grænseflade. Dette gør det og lettere senere at konvertere til andre tegningslibraries (skrive en ny facade til det nye library, men med samme grænseflade).
Avatar billede DeeDawg Nybegynder
31. december 2011 - 14:15 #5
Princippet i det er det samme. Vil give dig ret i at dit eksempel her, giver bedre indblik i hvordan man egentlig bruger det, men det er stadigvæk kun 2 sider af samme sag. :)
Avatar billede Smorkongen Nybegynder
20. januar 2012 - 18:53 #6
Takker for svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester