Asked  7 Months ago    Answers:  5   Viewed   29 times

This confuses me, in the most simplest terms what does it do? Pretend you are explaining to your mother or someone almost please.

 Answers

72

A factory creates an object. So, if you wanted to build

 class A{
    public $classb;
    public $classc;
    public function __construct($classb, $classc)
    {
         $this->classb = $classb;
         $this->classc = $classc;
    }
  }

You wouldn't want to rely on having to do the following code everytime you create the object

$obj = new ClassA(new ClassB, new Class C);

That is where the factory would come in. We define a factory to take care of that for us:

class Factory{
    public function build()
    {
        $classc = $this->buildC();
        $classb = $this->buildB();
        return $this->buildA($classb, $classc);

    }

    public function buildA($classb, $classc)
    {
        return new ClassA($classb, $classc);
    }

    public function buildB()
    {
        return new ClassB;
    }

    public function buildC()
    {
        return new ClassC;
    }
}

Now all we have to do is

$factory = new Factory;
$obj     = $factory->build();

The real advantage is when you want to change the class. Lets say we wanted to pass in a different ClassC:

class Factory_New extends Factory{
    public function buildC(){
        return new ClassD;
    }
}

or a new ClassB:

class Factory_New2 extends Factory{
    public function buildB(){
        return new ClassE;
    }
}

Now we can use inheritance to easily modify how the class is created, to put in a different set of classes.

A good example might be this user class:

class User{
    public $data;
    public function __construct($data)
    {
        $this->data = $data;
    }
}

In this class $data is the class we use to store our data. Now for this class, lets say we use a Session to store our data. The factory would look like this:

class Factory{
    public function build()
    {
        $data = $this->buildData();
        return $this->buildUser($data);
    }

    public function buildData()
    {
        return SessionObject();
    }

    public function buildUser($data)
    {
        return User($data);
    }
}

Now, lets say instead we want to store all of our data in the database, it is really simple to change it:

class Factory_New extends Factory{
    public function buildData()
    {
        return DatabaseObject();
    }
}

Factories are a design pattern we use to control how we put objects together, and using correct factory patterns allows us to create the customized objects we need.

Wednesday, March 31, 2021
 
mattltm
answered 7 Months ago
86

You should point to your vendor/autoload.php at Settings | PHP | PHPUnit when using PHPUnit via Composer.

This blog post has all the details (with pictures) to successfully configure IDE for such scenario: http://confluence.jetbrains.com/display/PhpStorm/PHPUnit+Installation+via+Composer+in+PhpStorm

Related usability ticket: http://youtrack.jetbrains.com/issue/WI-18388

P.S. The WI-18388 ticket is already fixed in v8.0

Wednesday, March 31, 2021
 
ojrac
answered 7 Months ago
37

Look into the Model-View-Controller Pattern

Wednesday, March 31, 2021
 
Raef
answered 7 Months ago
40

Yes, you can do this if your factory is a static method. It should work fine for the examples you have provided.

More details and some basic example can be found here: http://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata

Monday, August 2, 2021
 
macha
answered 3 Months ago
72

If you have the Martin Fowler's Refactoring book, just follow the "Change Unidirectional Association to Bidirectional" refactoring.

In case you don't have it, here's how your classes will look like after the refactoring:

class C
{
  // Don't to expose this publicly so that 
  // no one can get behind your back and change 
  // anything
  private List<W> contentsW; 

  public void Add(W theW)
  {
    theW.Container = this;
  }

  public void Remove(W theW)
  {
    theW.Container = null;
  }

  #region Only to be used by W
  internal void RemoveW(W theW)
  {
    // do nothing if C does not contain W
    if (!contentsW.Contains(theW))
       return; // or throw an exception if you consider this illegal
    contentsW.Remove(theW);
  }

  internal void AddW(W theW)
  {
    if (!contentW.Contains(theW))
      contentsW.Add(theW);
  }
  #endregion
}

class W
{
  private C containerC;

  public Container Container
  {
    get { return containerC; }
    set 
    { 
      if (containerC != null)
        containerC.RemoveW(this);
      containerC = value; 
      if (containerC != null)
        containerC.AddW(this);
    }
  }
}

Take note that I've made the List<W> private. Expose the list of Ws via an enumerator instead of exposing the list directly.

e.g. public List GetWs() { return this.ContentW.ToList(); }

The code above handles transfer of ownership properly. Say you have two instances of C -- C1 and C2 - and the instances of W -- W1 and W2.

W1.Container = C1;
W2.Container = C2;

In the code above, C1 contains W1 and C2 contains W2. If you reassign W2 to C1

W2.Container = C1;

Then C2 will have zero items and C1 will have two items - W1 and W2. You can have a floating W

W2.Container = null;

In this case, W2 will be removed from C1's list and it will have no container. You can also use the Add and Remove methods from C to manipulate W's containers - so C1.Add(W2) will automatically remove W2 from it's original container and add it to the new one.

Thursday, September 30, 2021
 
Peter Bridger
answered 4 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :