DEV Community

mohhamedion
mohhamedion

Posted on

Abstract Factory with builder

Hello, i have a design patterns test, in that test i have to do abstract factory with builder in one program, i am confused because builder and abstract factory are so similar, we can choose bettwen them but i can't see where we can combine them
can someone tell me if i did anything wrong here in this code?

<?php

interface YoutubeFactory{
public function createVideoLibrary();
public function createMuiscLibrary();
}

class YoutubeFactoryForAdults implements YoutubeFactory {
public function createVideoLibrary(){
return new AdultVideoLibrary();
}
public function createMuiscLibrary(){
return new AdultMusicLibrary();
}
}

class YoutubeFactoryForChildren implements YoutubeFactory {
public function createVideoLibrary(){
return new ChiledVideoLibrary();
}
public function createMuiscLibrary(){
return new ChiledMusicLibrary();
}
}
interface ILibrary {
public function render();
}
class AdultVideoLibrary implements ILibrary {
public $link;
public $author;
public function render(){
return 'render adult video';
}
}
class AdultMusicLibrary implements ILibrary {
public $link;
public $author;

public function render(){
    return 'render adult music';
}
Enter fullscreen mode Exit fullscreen mode

}

class ChiledVideoLibrary implements ILibrary {
public $link;
public $author;

public function render(){
    return 'render chiled video';
}
Enter fullscreen mode Exit fullscreen mode

}
class ChiledMusicLibrary implements ILibrary {
public $link;
public $author;

public function render(){
    return 'render chiled music';
}
Enter fullscreen mode Exit fullscreen mode

}

//
class YouTubeFactoryBuilder{
    public $factory;

    public function __construct($visitorAge){
        if($visitorAge>=18){
            $this->factory= new YoutubeFactoryForAdults();   
        }else{
            $this->factory= new YoutubeFactoryForChildren();   
        }
    }

    public function createNewFactory($factory_object){
         $this->factory = $factory_object;

    }

    public function getFactory(){
        return $this->factory;
    }
}
Enter fullscreen mode Exit fullscreen mode

///client code

$bulder = new YouTubeFactoryBuilder(rand(0,100));
$factory= $bulder->getFactory();
$videoLibrary = $factory->createVideoLibrary();
$musicLibrary = $factory->createMuiscLibrary();

 echo $videoLibrary->render()."\n";
 echo $musicLibrary->render();
Enter fullscreen mode Exit fullscreen mode

Discussion (2)

Collapse
dakujem profile image
Andrej Rypo • Edited on

I believe your example is wrong.

Imagine a builder as an object that allows us to configure the object inside the builder that comes out at the end.

Imagine a factory as an interface with a create method and a type that comes out.

That's it, really.

If you need to combine the two,

$builder = new FactoryBuilder();

$factory = $builder
    ->installDieselEngines() // the factory will install diesel engines
    ->installAutomaticTransmissions() // with automatic transmissions
    ->build();   // build the factory
$car1= $factory->create();
$car2= $factory->create();

$anotherFactory = $builder
    ->installPetrolEngines() // this factory will install petrol engines
    ->installManualTransmissions() // with manual transmissions
    ->addPerformancePackages() // and will produce sports cars
    ->build();
$sportsCar= $anotherFactory->create();
Enter fullscreen mode Exit fullscreen mode

Please note that both factories should have the same interface (or be the same class), and the cars produced should have one too.

I will come back to you tomorrow, if it's not clear to you. I'm on a phone now. Let me know.

(I edited the answer for more explanation and legibility)

Collapse
dakujem profile image
Andrej Rypo

@mohhamedion let me know if you need anything else.