While I have been developing objects for PHP for some time now, abstract classes are somewhat new to me. From my understanding, I would use an abstract class when I want to define a list of methods I want myself or other developers to follow, while also providing some base methods to build upon.
It appears there is no way to define properties within an abstract class however, which I find odd. Take the following code:
abstract class Gateway {
abstract public function process();
public function set_gateway_key( $key ) {
$this->key = $key;
}
}
A key of this sort is something you would typically want to restrict access to in order to run through some kind of validation. You could probably imagine some other scenarios as well. However, you are forced to rely on the developer extending this abstract class to set this access modifier.
Am I missing something? Or is there no way to do this?
Abstract classes can have properties.
abstract class AbstractClass {
protected $key;
public function setKey($key) {
$this->key = $key;
}
}
Related
I have an abstract class like this
<?php
abstract class AbastractCreationCommand extends AbstactCommand {
protected $repository;
function handle($payload) {
$this->repository->create($payload);
}
}
class TagCreationCmd extends AbstractCreationCommand {
function __constructor() {
$this->repository = new TagRepository();
}
}
?>
Questions:
is there a way I could enforce the definition of the repository class in the subclasseses of the AbstractCreationCommand ?
Do I need to create a test for each subclass and call handle method or is another way to test all my code?
Answering number 1: You cannot enforce the creation of anything in subclasses from within your abstract class. At least not during instantiation. Everything in the subclass is optional.
However, your code in the abstract class could check whether or not the necessary objects have been defined when executing the part of the code that needs it, like this:
abstract class AbastractCreationCommand extends AbstactCommand {
protected $repository;
function handle($payload) {
if (!$this->repository instanceof TagRepository) {
throw new \InvalidArgumentException('Need a TagRepository');
}
$this->repository->create($payload);
}
}
However, is likely doing the complaining too late. And the reason may be because you are using inheritance instead of composition, or are inheriting the wrong things.
First of all, you are not doing dependency injection. Your subclass should not directly instantiate that TagRepository. This leads to problems testing your abstract class' code, as well as the subclass code, because you cannot provide a mock object instead. This severely limits the ability to test your code in isolation.
Also, the subclass cannot work without knowing very specifically how to inherit the abstract class beyond implementing any abstract functions. If both abstract and subclass come from you as the author, I would consider it to be ok to impose doing all things correctly on you. But if you expect other developers to inherit that abstract class (and your question sounds like this might be the background problem), then you shouldn't do this at all.
Abstract classes do provide some common functions to a set of subclasses through inheritance. But the same thing could be achieved if you put all the code into a non-abstract class and inject this class into independent ex-sub classes. They will call these common functions as public methods instead of private or protected, and the testing of the common code is also easier, because the methods are public.
Also note that you already have three levels of inheritance, which is nearing a uncomfortable level: AbstractCommand -> AbstractCreationCommand -> TagCreationCmd.
The problem is that everything you change in AbstractCommand has to be done with two levels of inheriting objects in mind. You cannot simply change a protected variable's name. You cannot simply add a protected (or public) variable without checking if any of the sub classes already has such a variable with the same name - unless you intend to share it.
The problems with maintaining code that is inherited is not with the classes at the end of the inheritance chain, but with these at the top. Just think about how many classes might be affected with different usage contexts: If you have AbstractCreationCommands, you will have AbstractDeletionCommands and AbstractChangeCommands and AbstractDoNothingCommands, and a plethora of concrete commands of all these kinds doing plenty of different stuff. Just imaging that on each level, you have four classes - this makes you having to maintain one base class, four inheriting classes, and four times four concrete classes - for a whopping 21 classes in total, all of them having to be tested, and likely none of them gaining any benefit from being an instanceof AbstractCommand.
Answering number 2: Yes, you have to test all subclasses - these are the ones that get instantiated and used. You should also test the abstract class' code in isolation. PHPUnit offers to instantiate an abstract class with the mock framework, so any abstract method would be mocked and could be configured. However, I always have a bad feeling when I use a mock as the real tested object because I am not really testing the pure code, but some combination of mock code and real code.
A possible way out is to create a test class that barely does anything beyond extending the abstract class, and work with this one.
1.Yes. I do the same when I need to force instantiation of some dependancies. And this way is support GRASP: Creator principle.
Another way to accomplish that with dependency injection, but this way broke Creator principle:
class TagCreationCmd extends AbstractCreationCommand {
function __constructor(TagRepositoryInterface $tagRepository) {
$this->repository = $tagRepository;
}
}
If follow 3 rules of TDD you should write test for each line of code. So the answer is yes.
Is there a way I could enforce the definition of the repository class in the subclasseses of the AbstractCreationCommand ?
I don't see the necessity tbh. If your AbstractCreationCommand needs a repo to work, add it as a constructor param. This doesn't enforce the repo to be injected because a subtype can override the constructor, but it should be abundantly clear that an AbstractCreationCommand subtype requires some sort of repo then, e.g.
abstract class AbstractCreationCommand extends AbstractCommand
{
private $repository;
public function __construct(Repository $repository)
{
$this->repository = $repository
}
protected function getRepository(): Repository
{
return $this->repository;
}
// …
You could also use a Template Method pattern to indicate that any subtype will utilize a repo by adding an abstract getter for the repo. The subtype will have to implement that method then. It's then up to the developer to decide on the implementation:
abstract class AbstractCreationCommand extends AbstractCommand
{
public function handle()
{
$this->getRepository()->create();
}
abstract function getRepository(): Repository;
// …
If you really must enforce it at creation level, you can set the abstract type's constructor to final protected and do any subtype creation in a static factory method, e.g.
abstract class AbstractCreationCommand extends AbstractCommand
{
private $repository;
final protected function __construct(Repository $repository)
{
$this->repository = $repository;
}
// …
This now prevents direct instantiation of any subtypes via new. Trying to new a subtype, will result in PHP Fatal error.
Instead the subtype must be created like this:
class TagCreationCommand extends AbstractCreationCommand
{
private $foo;
public static function create(Repository $repository, Foo $foo)
{
$command = new static ($repository);
$command->setFoo($foo);
return $command;
}
protected function setFoo(Foo $foo)
{
$this->foo = $foo;
}
// …
Then you'd call TagCreationCommand::create(new TagRepository, new Foo); to get a new instance. Since you cannot override the constructor and have to call the parent constructor from within the static create method, you effectively enforce a Repository now to be there. I added the Foo stuff only to illustrate how you'd use additional dependencies.
As you can hopefully see, this requires quite a lot of gymnastics compared to the much more lightweight previous two approaches that will basically result in the same outcome. After all, if there is no repo, the code will fail. And since you are using tests, this will get noticed. So why bother?
Do I need to create a test for each subclass and call handle method or is another way to test all my code?
If you are overriding the handle method, you should test that behavior in a concrete test class for that subtype.
If your subtypes do not override the handle method, you can create an AbstractCreationCommandTest and put a test for the handle method in there. However, if that is the case, I wonder why you need the AbstractCreationCommand to be abstract in the first place because then it sounds like you just need a CreationCommand.
Following Yan Burtovoy's suggestion, I would go even further and actually enforce a DI container
<?php
abstract class AbastractCreationCommand extends AbstactCommand {
protected $repository;
function __constructor(\DI\Container $container) {
$this->repository = $container->get('TagRepository');
}
function handle($payload) {
$this->repository->create($payload);
}
}
You should create tests for everything that is exposed to users of your library (that would be your application).
So, if you have a subclass that relies on handle() being called then you should write a test for that. Reason being that in 6 months someone might change the inheritance or overwrite the handle() method and change the initial expected behaviour.
While this question is about methods of solving this problem, I am particularly interested in good clean OO design and solutions that conform to current PHP best practices. Thanks in advance for taking a look.
I have the following interface:
<?php
interface Tool {
/**
* Return the unique name of the tool
*/
public function getName();
}
The majority of classes that implement this interface in my project looks like this:
<?php
class Drill implements Tool {
protected $toolName = 'drill';
public function getName() {
return $this->toolName;
}
}
And so the problem is I have dozens of classes that repeat this logic, duplicating the $toolName property and getName() logic, breaking the simple rule of 'Don't repeat yourself'
One solution I have considered is the following:
<?php
abstract class BaseTool implements Tool {
public function getName() {
return $this->toolName;
}
}
Then simply have tool classes extend the abstract BaseTool class:
<?php
class Drill extends BaseTool {
protected $toolName = 'drill';
}
However this now means that I lose the ability to force implementing classes to define the function getName() if they extend the BaseTool class, which can lead to incorrect implementations.
I also think that by having the BaseTool class return $this->toolName, it is making assumptions about the implementing classes and breaks encapsulation.
I have used a simple example to demonstrate the problem but hope you get what I'm trying to solve, and that this problem may also relate to more complex situations. Appreciate your thoughts.
If you're using PHP 5.4.0+, check out traits!
You could create a ToolInterfaceTrait that just contains the getters / setters for the variable $toolName
Your attempt looks good. Nothing more to say.
However this now means that I lose the ability to force implementing classes to define the function getName() if they extend the BaseTool class, which can lead to incorrect implementations.
You still force them, they need to inherit a class which implements them or implement them on their own.
If it is not feasible that all classes which should implement Tool extend from BaseTool, feel free to create more base classes which implement getName() or implement it directly, like you wish.
Btw, if you plan that all tools should extend BaseTool, then the interface isn't necessary at all, at least not for this use case. Interfaces are used for situations where not all classes which are expeted to implement it are inherited from the same base class.
How to avoid duplicating implemented getter function in PHP
Abstract classes are often used to group duplicated code. You're on the right path. As for your doubts about the choice...
However this now means that I lose the ability to force implementing classes to define the function getName() if they extend the BaseTool class, which can lead to incorrect implementations.
By extending the BaseTool class, a class inherits getName() (that's the idea with defining it in the abstract class). I'm not sure why that leads to incorrect implementations or why you'd have to "force implementing classes to define it." They get it automatically by extending the abstract class.
I also think that by having the BaseTool class return $this->toolName, it is making assumptions about the implementing classes and breaks encapsulation.
It might be cleaner if you define the toolName in the abstract class, and you set its value in the constructor?
<?php
abstract class BaseTool implements Tool {
protected $toolName;
public function __construct($toolName)
{
$this->toolName = $toolName;
}
public function getName() {
return $this->toolName;
}
}
You define a constructor in the extended class to put its name:
<?php
class Drill extends BaseTool {
public function __construct()
{
parent::__construct("drill");
}
}
While doing some tutorials on Decorator pattern, I've encountered two different implementations.
Implementation 1 (referred to as I1)
Implementation 2 (referred to as I2)
In short,
I1's parent decorator class implements original object's interface (In the example, class PropertyDecorator implements PropertyInterface. The original object Property implements PropertyInterface as well).
I2's parent decorator class DOES NOT implement original object's interface (In the example, Decorator_Wrapper does not implements Cupcake interface. In fact, there is not even CupcakeInterface at all).
My question is,
Is this merely a personal preference of understanding and implementing Decorator pattern? or one is wrong and one is right?
Just depends on your needs.
Let's see:
Abstract class
Can provide abstract methods.
Can provide real functions and variables.
Can be extended. But a class can extend only 1 parent.
Interface
Can provide abstract methods.
A class may implement several interfaces.
I generally would prefer using a base abstract class, because I can declare some basic functions as well, since you could have a lot of different types of decorators with similar functionality. Methods can be overriden anyways + you can implement some interfaces.
class Decorator extends Decorator_Wrapper implements Interface1, Inteface2 {
public function __construct(){
parent::__construct() ; // Here you could perform some basic decorator actions. It is an advantage compared to interfaces.
}
}
The Decorator pattern is used when you wish to extend the functionality of an instance of a class without extending the class itself (thus, not affecting other instances of said class).
It's kind of an extension at runtime and it's pretty useful since it lets you customize the behavior of an object at runtime. You can even "simulate" multiple inheritance with it.
Since both your examples accomplish this, both are correct. There is no need for a decorator to implement the base interface or extend the original object.
HOWEVER...
If the decorator does not implement the base interface, it MIGHT not be able to be used interchangeably with the original class.
Which might defeat the purpose of using the decorator if you can't use it everywhere "safely".
Example:
interface FooInterface {
public function scare();
}
class Foo implements FooInterface {
protected $boo = 'boo';
public function scare() { echo $this->boo; }
}
class FooBar {
public function __construct(FooInterface $foo) {
$this->foo = $foo;
}
public function scareAlot() {
echo strtoupper($this->foo->scare());
}
}
class INeedFoo {
public static function gimmeFoo(FooInterface $foo) {}
}
$foo = new Foo();
$fooBar = new FooBar($foo);
INeedFoo::gimmeFoo($foo); //Works
INeedFoo::gimmeFoo($fooBar); //Does not Work
Also, if you implement the base interface or extend the base class it might be easier to add multiple decorators on top of eachother but ... you may also end up with a lot of replicated functionality.
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.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
PHP: What is the difference between an interface and abstract class?
As far as I understand, a class implements or extends abstract or interface class has to use the default methods. I know we can use implement keyword to use multiple interfaces, but we only can extend 1 abstract. Which one to use in real life project and the difference?
The differences are both theoretical and practical:
interface is a description of some capability your class has and advertises (so various classes implementing the same interface can be used the same way)
abstract class can be a default implementation, containing the parts which are likely to appear in all the implementations. It doesn't have to implement the complete interface
Example - an interface:
// define what any class implementing this must be capable of
interface IRetrieveData {
// retrieve the resource
function fetch($url);
// get the result of the retrieval (true on success, false otherwise)
function getOperationResult();
// what is this class called?
function getMyClassName();
}
Now we have the set of requirements that will be checked for every class implementing this. Let's make an abstract class and its children:
// define default behavior for the children of this class
abstract class AbstractRetriever implements IRetrieveData {
protected $result = false;
// define here, so we don't need to define this in every implementation
function getResult() {
return $result;
}
// note we're not implementing the other two methods,
// as this will be very different for each class.
}
class CurlRetriever extends AbstractRetriever {
function fetch($url) {
// (setup, config etc...)
$out = curl_execute();
$this->result = !(curl_error());
return $out;
}
function getMyClassName() {
return 'CurlRetriever is my name!';
}
}
class PhpRetriever extends AbstractRetriever {
function fetch($url) {
$out = file_get_contents($url);
$this->result = ($out !== FALSE);
return $out;
}
function getMyClassName() {
return 'PhpRetriever';
}
}
A completely different abstract class (unrelated to the interface), with a subclass which implements our interface:
abstract class AbstractDog {
function bark() {
return 'Woof!';
}
}
class GoldenRetriever extends AbstractDog implements IRetrieveData {
// this class has a completely different implementation
// than AbstractRetriever
// so it doesn't make sense to extend AbstractRetriever
// however, we need to implement all the methods of the interface
private $hasFetched = false;
function getResult() {
return $this->hasFetched;
}
function fetch($url) {
// (some retrieval code etc...)
$this->hasFetched = true;
return $response;
}
function getMyClassName() {
return parent::bark();
}
}
Now, in other code, we can do this:
function getStuff(IRetrieveData $retriever, $url) {
$stuff = $retriever->fetch($url);
}
and we don't have to worry which of the retrievers (cURL, PHP, or Golden) will be passed in, and how are they going to accomplish the goal, as all should be capable of behaving similarly. You could do this with an abstract class, too, but then you're restricting yourself based on the classes' ancestor, instead of its capability.
Multiple vs. single inheritance:
You can only inherit from a single abstract class
You can implement multiple interfaces
Implementation:
An abstract class can actually have functioning code in it. This lets you share implementation between the child classes
An interface only defines public member functions. Classes implementing the same interface don't actually share code.
That's what I know off the top of my head.
The metaphor I heard best was that an abstract class is a half-completed class. It's not done; you still have to finish it. So when you make a class that extends an abstract class, you are just completing what you began in the abstract class. This is also why you can't instantiate an abstract class; that you've made it abstract indicates that it's incomplete. It still needs some additional functionality.
An an interface just guarantees that certain methods, each with a certain number of arguments, must exist within a class that implements it. So that later on, a programmer who uses a class that implements a particular interface can rest assured that they can call certain methods on that class.
See this page: 5 Main Difference between Abstract class and Interface in PHP
And this: related StackOverflow answer.
Here's a good description of the differences between the two:
http://www.supertom.com/code/php_abstracts_and_interfaces.html
It all boils down to the fact that extends is a "is-a" relationship while implements is a "has-a" relationship.
"An Abstract Class can contain default Implementation, where as an
Interface should not contain any implementation at all. "
As far as which to use in real world application... it really comes down to context.
For example, there was a question on here the other day about implementing a game using PHP. Here they had a abstract class defining a monster and any monster could be based off of this abstract class. This allowed for inheritance of default monster properties.
Whereas for an interface, you are defining a general requirements for a way to "interface" (pardon using the term in the explanation) some system. An example of this from a recent project I did. I implemented a soapclient in php to interact with a soapserver from a third party. This interface defines what soap methods the server supports and thus any class implementing my interface must define those methods.