Say I have a class A that has another class B as its property.
When class A needs to do modifications to class B, is it better to use the getter method to do modifications or access the property directly to access?
So as an example.
public class Car() {
private $engine;
public function __constructor() {
$this->$engine = new Engine();
}
public function getEngine() {
return $this->engine;
}
public function replaceEngine() {
// Should I use
$this->engine->change();
// Or should I use
$this->getEngine()->change();
}
}
I am thinking using the getter method so that if I had to stub Class Engine methods, I can mock what getEngine() returns and remove the dependency.
But I'd like to see more opinions on this.
Thank you!
Opinion based questions don't do well on stack overflow, but you really should use getters and setters.
This method is better programming practice for several reasons.
-You can easily use mock classes
-If you need the class to update in response to have an attribute change (or may in the future). E.g: The setSpouse function can update both the 'spouse' and 'relationshipStatus' attributes
-If you ever want to do refactoring
Related
I want to disable a class to be instantized by new operator, but lets suppose a getObject method what creates and returns an instance of it. Is it doable?
class C
{
protected function __construct()
{
}
public static function getObject()
{
return new self();
}
}
UPDATE:
The code above fulfills the requirement: the class cannot be instantiated using new, one needs to use the factory method getObject() to create an object. However, the OP did not specify the reason they need such a construct.
There are several reasons such a design emerges; one of them is when the creation of objects of type C needs to be completed with some initialization that, for whatever reason, cannot be done in the class' constructor.
Another reason for this way of constructing objects of class C is the Singleton design pattern; which in fact is an "anti-pattern", but this is another discussion; in order to implement a Singleton, class C should look like this:
class C
{
private static $instance = NULL;
protected function __construct()
{
}
public static function getObject()
{
if (! isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
}
Singleton or not, because method getObject() is static it cannot be stubbed or mocked by the test frameworks and its original implementation have to be used. More, because it is the only way to create objects of class C, other classes that use this class cannot be tested in isolation.
All in all, even the construction is possible, it is not recommended. Enforcing the creation of objects of class C using language mechanisms made the class a nuisance for testing other classes that use it.
If the creation of objects of class C needs to be done by a certain method because of its complex initialization, a better way is use the Builder design pattern. Make it a non-static method of another class (the "builder") and instruct the programmers (using the class documentation) to not create objects of class C directly, using new. This way it does not affect the testability of other classes.
I want to disable a class to be instantized by new operator
A common approach is to privatize the constructor.
class Example {
private function __construct() {
}
}
The following would result in a fatal error.
$object = new Example();
While this will work, I would encourage you, and future readers, to review Design Patterns in PHP.
I am new to PHP and just get into OOP. I have few generic methods used to set and get properties. I use them quite often in almost all the classes, i put those methods in a class and extends other classes from it. Now i can access the methods from child class but dont know how set and get attributes of child class through them ... parent class base.php
class Base
{
public function __construct()
{
}
function __set($propName, $propValue)
{
$this->$propName = $propValue;
}
function setProperties(array $data)
{
foreach($data as $propName => $propValue)
$this->$propName = $propValue;
}
function __get($propName)
{
return (isset($this->$propName))? $this->$propName : "Invalid property!";
}
function getProperties(array $properties)
{
foreach($properties as $propName)
$propVals[$propName] = $this->$propName;
return $propVals;
}
}
child class categories.php
class categories extends Base
{
private $id;
private $pid;
private $title;
private $status;
public function __construct()
{
parent::__construct();
}
}
and i called it like
$objCat = new categories();
$objCat->setProperties(array('id'=>'10', 'pid'=>'6'));
print_r( $objCat->getProperties(array('id', 'pid')));
Need little guidance here. If its the right way? or at least is it possible to do it like this? if so how to accomplish this ...
thanks
Extending a class is something you only want to do when you can say class categories is a class Base. Something like that sort of utility class you have their is almost always the wrong way to go. PHP also has introduced something called traits for copy/paste code. However my personal preference is that it is something you will never want to use, because it tightly couples the traits to your class, which is something you want to avoid.
See for more information the Liskov Substitution principle in SOLID programming.
If it was up to me I would avoid those magic getters / setters either way and just add your own getters / setters methods to the class.
The mistake about some base class isn't something only you are doing (hell even I have done it in the past). Think about some class Database and a class Article. Because the Article class needs access to the database many people let the class extend the Database class. This isn't correct because an article isn't an database. Instead an instance of the database class should be injected into the article class by using dependency injection. The instance should either be injected into the class constructor (if all or many methods need access to it) or just the methods that need it. So when extending a class you have to be able to say class B is a class A.
Some other notes about your code:
Always make your class names PascalCase. This is not really required to make your code work, but it follows a naming convention often used.
And my personal preference a bit: please always add curly braces to your foreach statements. It is more clear what is happening when other people are reading your code.
Here is a simple example:
class Class_A {
protected $_property;
public function method()
{
Class_B::method($this);
}
public function getProperty()
{
return $this->_property;
}
}
class Class_B {
public static function method(Class_A $classA)
{
$classA->getProperty();
}
}
$classA = new ClassA();
$classA->method();
Is it ever okay to pass $this as a parameter to the method of another class? Or is that always going to be tight coupling? I could pose another similar example using a Factory Pattern in place of the static method call.
It depends on the exact behaviour of Class_A and Class_B, but in general it would probably be better to define an interface which is implemented by Class_A and type hint for that. The methods of Class_A that are required by Class_B (e.g. getProperty()) should appear in your interface. Then, if you want to switch Class_A with another class at a later date, all it has to do is implement the same interface.
Yet again, it depends on the behavior of the classes in question, but if there was another Class_C for example that also used Class_B 's static method you might want to consider having Class_A and Class_C extend Class_B. More information can be found on the php object inheritance page.
I am implementing the state pattern in one of my projects and is running into a design issue; my problem can be abstractly described as follows:
Let's say I have the StatefulObject Class that has a state property which holds the CurrentState object.
Much of the functionally I'd like the CurrentState object to access, is encapsulated in the StatefulObject object.
The problem is that allowing access to this functionality forces me to provide public methods in the StatefulObject class that I would otherwise have not exposed, and also feel I shouldn't.
I'd welcome suggestions on how to handle this visibility issue.
The implementation language is PHP, if that maters.
I've put together some example code, according to request:
Class StatefulObject{
protected $state;
public function StatefulObject(){
$this->state = new PrepareSate($this);
}
public function execute(){
$this->state->execute();
}
/* I am not intrested in providing public access to these methods
Optimaly I would have this visible only for the PrepareState*/
public function setX(){
};
public function setY(){
};
}
Abstract class StateObject{
protected $stateFulObjectRef;
public function StateObject(StateFulObject $ref){
$this->stateFulObjectRef = $ref;
}
}
Class PrepareState extends StateObject{
public function execute(){
/* This is why I need the public access for */
$this->stateFulObjectRef->setX();
$this->stateFulObjectRef->setY();
}
}
I think that the solution in Java would be having the methods setX setY with no access modifier, which means they will be visible at package level.
I don't think PHP has an equivalent solution though.
EDIT, on to possible answer:
I think the best solution I came up with so far is making StatefulObject and the StateObject inherit the same father (solely for visibility). and the declare the setX setY methods as protected. Sibling classes has access to each other protected methods in PHP - as pointed out here - http://www.php.net/manual/en/language.oop5.visibility.php#93743
The question is very general but I will try to answer based on my understanding of your problem (which could be not a correct understanding of the problem)
I will suggest that you make an interface and implement it in your class and than use that interface object to interact with the methods.
If your StateObject does not need access to the StatefulObject at all, then just simply pass the needed values in parameters(Strategy pattern).
Class StatefulObject{
protected $state;
public function StatefulObject(){
$this->state = new PrepareSate($this);
}
public function execute(){
$this->state->execute($this->x, $this->y);
}
}
Class PrepareState extends StateObject{
public function execute($x, $y){
// Now you have access to $x and $y.
}
}
This article is similar to my needs, but I'm more curious about a specific solution to it, and if it's a good or bad idea to do it. Sharing objects between PHP classes
Say, like in the link above, I have an object I want to pass to multiple classes, say a $db object.
Instead of using dependency injection and passing it to each method's constructor, is it ever a good idea to let all the classes extend a Base class, that stores the $db object as a property?
For example:
abstract class Base {
protected static $_db;
public function setDatabase( Database $db ) {
$this->_db = $db;
}
public function getDatabase() {
return $this->_db;
}
}
class SomeClass extends Base {
public function doStuff() {
$result = $this->getDatabase()->query(.....);
}
}
Which would mean all classes that extend Base need not worry about grabbing/checking/setting the $db themselves, as they'd already have that object as a property as soon as the class is defined.
I know dependency injection is the usual way to go, but is this ever a viable solution?
Thanks!
You still have to set the db on each instance of the class - setting it on one instance doesnt set it on all instances... unless of course its a static property.
That is perfectly fine. I have used it before and never ran into any issues.