I have a class called Assembly
that hides implementation of underlying products. ProductA
can have one set of getters, ProductB
can have another.
While PHP is quite forgiving and if I don't mix up Products and getters, my code will work, but there is no protection offered for when I do mess up and populate Assembly
with ProductA
, but then use a getter from ProductB
.
Also, my IDE does know the methods from either class, so there is no auto-complete offered when I work inside Assembly
with getters from either Product
.
I want more bullet-proof code, one where Assembly
knows or is aware of which Product
subtype it currently hosts. Is there a way to do so?
Sample below
class Assembly
{
private $product;
public function setProduct(Product $product) {
$this->product = $product;
}
public function getA() {
return $this->product->getA();
}
public function getB() {
return $this->product->getB();
}
}
class Product { }
class ProductA extends Product
{
public function getA() {
return "A";
}
}
class ProductB extends Product
{
public function getB() {
return "B";
}
}
//set assembly
$assembly = new Assembly();
//define product sub-type
$product = new ProductB();
//place product into assembly
$assembly->setProduct($product);
//assembly has no clue which subtype it has
print $assembly->getB(); // "B"
print $assembly->getA(); // prints nothing
Interface Suggestion
interface CompositeProductInterface
{
public function getA();
public function getB();
}
//update code in Assembly to:
public function setProduct(CompositeProductInterface $product)
{
$this->product = $product;
}
This gives me autocomplete in my IDE, which is nice, but doesn't solve my other issues. Also I am a little eerie on mushing things together into a single "composite" product.... It seems more like a work-around. In my specific case I have two very similar products that differ on some minute things like a few properties.
Real World Example
Both Product models A and B have an engineering drawing that lists variables to identify various product dimensions. Named dimensions are similar across both products. For example, M1 on product A means the same physical dimension on product B. However, Product A has features not present on product B and vice versa.
If that still feels too hypothetical, the actual dimensions on the actual drawing are listed as B2, and B3. These dimensions (B2, B3) are not present on the other product model. I want to be able go use an assembly construct to list variables on the drawing, including M1, B2, B3, and so on. I could do so with
print $assembly->getM1(); //works for both products
print $assembly->getB2(); //works for one product only
print $assembly->getB3(); //same as above
Goal
Goal is to have a single class (assembly) responsible for listing named dimension variables, and each product only know itself. So
I do not feel this is the right solution, but what you ask for could be achieved in the following way.
get_class($product);
Will tell you which class $product
is. Which would lead to the following code:
private $product;
private $productClass;
public function setProduct(Product $product) {
$this->product = $product;
$this->productClass = get_class($product);
}
Or:
public function getProductClass(){
return get_class($this->$product);
}
Which could leads to a check similar to:
public function getA() {
if($this->productClass === "ProductA")
return $this->product->getA();
}
As well documented in:
http://php.net/manual/en/function.get-class.php
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With