I am trying to work out the best way to design my classes and I think abstract classes it the right way here, but I'm not sure! I am building a plugin for Wordpress carts that at the moment, will work for both Woocommerce and WP-Ecommerce. As these two systems have different implementations of certain functionality, such as getting an order object, I want to create a separate class for each platform.
I have the following which will contain generic methods that should be available to the classes that inherit from it. This class should never be instantiated:
class Order_Export {
}
I then have 2 more classes that will inherit from the above:
class Order_WooExport extends Order_Export {
}
class Order_WPExport extends Order_Export{
}
Is my design right here? Am I right in saying the class Order_Export should be an abstract class? What about methods that I want the class inheriting to implement? Do I simply mark the signature in the abstract class and not provide a body, or do interfaces come into play somewhere here?
How about instantiating the right class? Do I create a factory that will return one or the other?
Any advice appreciated!
That sound correct to use abstract base class, as long as you are sure to never need to instantiate Order_Export :
abstract class Order_Export
{
abstract protected function someMeth1();
abstract protected function someMeth2();
public function someMeth3() {
// Do common thing to both Order_WooExport and Order_WPExport
// using someMeth1(), someMeth2()...
}
}
Then :
class Order_WooExport extends Order_Export
{
protected function someMeth1() {
// Do something specific
}
protected function someMeth2() {
// Do something specific
}
}
Finally, the factory seems to be the right way to go too.
Related
Is there any clear difference why to use abstract for extends if we can do same in with the normal class excepts it doesnt provide the contract for eg.
abstract class Survivalneeds {
abstract public function eat(); // everyone eats but different foods which would probably work as contract
public function breathe() {
// everyone inhale o2 exhale co2 only for animals
}
}
Now
class human extends Survivalneeds {
protected function eat() {
//sometimes eat goat
// contract
}
breathe()// already extending having same functionality inhale o2 and exhale co2
}
class goat extends Survivalneeds{
protected function eat() {
//wee eat greens
// contract
}
breathe()// already extending having same functionality inhale o2 and exhale co2
}
Now the same functionality can be granted by normal class by extending except the contract method and for contract we could use interface also.
What you are saying its correct inheritance works in both cases but the idea of an Abstract class is that its some common logic shared by x classes that extend this functionality but that is not instantiable by it self because it doesn't make sense (maybe you want only to have types of cars in your system but not a generic car that doesn't have a brand)
Also if you will use regular class and interface you will be forced to create stub in a class in order to follow the contract. So you will be able to create the instance of the class. And just imagine you will use this common function in your upper class.
interface Crashable{
function crash();
}
class Car implements Crashable{
function crash(){}
function getCrashParams(){
return $this->crash();
}
}
class Volvo extends Car{
function crash(){
parent::crash(); // will be OK that it's not right
//.. specific params
return $params;
}
}
class Saab{
function crash(){
//.. specific params
return $params;
}
}
$car = new Car(); // will be ok, that it's not right
//getCrashParams() function in a Car will use the local version of the crash() and not the function of it's child that will kill the data flow
You should use an interface whenever you have a need for a contract. You should use abstract class in case there's a common functionality for some simmilar classes and you don't want to repeat the code (DRY :). Of course, it is always better to use composition, but this is not the time for this discussion :)
The problem with your code (with Survivalneeds class) is the fact the class from one side is responsible for the contract (breathe and eat methods) and from another is responsible for providing common functionality. You could change your code in following way:
interface Survivor {
public function eat();
public function breathe();
}
abstract class Survivalneeds implements Survivor {
public function breathe() {
// method's body
}
}
With such implementation responsibilities are splitted. Also it is clear that all classes that will extend Survivalneeds will need to as well fulfill Survivor contract.
I am creating a reporting library in PHP and developed an abstract class named ReportView. This will provide the basic functionality of a report like Generating header and footer, create parameter form.
There will be another function named generate_report in this class. Currently it is empty in abstract class as at this level we do not know the contents of report. Further it includes a render function which calls this generate_report function and sends output to browser.
So I need whenever a child class inherits from ReportView it must implement
the generate_report method otherwise PHP must give error. Is there any keyword or method through which we can enforce implemetation of a specific function.
Do the following:
abstract class ReportView {
abstract protected function generate_report();
// snip ...
}
class Report extends ReportView {
protected function generate_report() { /* snip */ }
}
Any class that extends ReportView and is not abstract must implement generate_report (and any other abstract function in its super classes for that matter).
Sounds like you’d be better off creating an interface, which would enforce you to define those methods in classes that then implement this interface.
<?php
interface ReportInterface {
public function generate();
}
class MyReportClass implements ReportInterface {
}
Instantiating MyReportClass here will throw a fatal error, telling you generate() has not been implemented.
Edit: You can also create abstract classes that implement this interface. You can have your abstract class contain any methods all extending classes need, and have your interface define any methods you need to be defined by extending classes.
You need to declare the method as abstract as well (and don't give it a method body), otherwise the derived classes will not be forced to implement it.
Alternatively, you could implement the method but have it just throw an Exception (not sure why you would want to do this).
Lastly, if all the methods in your base class are "abstract" (do not have bodies) then you can make the class into an Interface instead.
Here's the basic premise, I'm using an active record pattern for db objects, and I think I need some direction how to organize these classes. And also in general how I could potentially split up my class structure. Hopefully I don't explain this too terribly. If composition pattern is the way to go I may need a little hand holding on a way to implement it.
Let's say there's the ActiveRecord base class, at the bottom of the totem pole that deals with mapping objects to the db and the db to objects.
A child of ActiveRecord is a sort of generic User class, that deals with user sessions, logins, encryption of the password field on save and such.
Another child of ActiveRecord is a ActiveRecordButSlightlyMoreAdvanced class. Usually this class has nothing to do with User, but here's my issue.
I want to have a subclass that wants to be essentially a combination of User and ActiveRecordButSlightlyMoreAdvanced; UserButSlightlyMoreAdvanced, without having to copy paste all of the methods from User. It doesn't make sense for User to extend ActiveRecordButSlightlyMoreAdvanced, as it'd require essentially overriding a bunch of methods that have undesirable behavior for User.
It would make sense for UserButSlightlyMoreAdvanced to extend ActiveRecordButSlightlyMoreAdvanced, but I'd have to copy and paste a bunch of methods from User.
I know some people think better with pictures, so here's the structure illustrated.
Base
class ActiveRecord
{
....
}
Child
class User extends ActiveRecord
{
....
}
Also Child
class ActiveRecordButSlightlyMoreAdvanced extends ActiveRecord
{
....
}
The Problem
class UserButSlightlyMoreAdvanced extends User AND ActiveRecordButSlightlyMoreAdvanced
{
:( :( :(
}
I've been thinking about this problem for about a month now and cannot think of a solution that doesn't place burden of maintaining the objects dually if there's a change to how one of them implements saving. I'm going to experiment with a few solutions over the next couple of days and possibly post what I think was best in this situation.
My guess is that you meant to say this:
class UserButSlightlyMoreAdvanced extends User AND ActiveRecordButSlightlyMoreAdvanced
{
:) :) :)
}
If that is the case, look into traits http://php.net/manual/en/language.oop5.traits.php
You might try using the strategy pattern. In this case you would create your class:
class UserButSlightlyMoreAdvanced extends ActiveRecord implements ActiveRecordButSlightlyMoreAdvancedStrategy
{
private $_strategy;
public function useStrategy(ActiveRecordButSlightlyMoreAdvancedStrategy $s) {
$this->_strategy = $s;
}
}
and make your strategy class:
interface ActiveRecordButSlightlyMoreAdvancedStrategy
{
// Define what this should do here
}
Make a strategy class that implements the above interface.
class ActiveRecordButSlightlyMoreAdvanced implements ActiveRecordButSlightlyMoreAdvancedStrategry {
// Do stuff here
}
Now when you call those advanced methods, both classes implement the same interface, but the UserButSlightlyMoreAdvanced class just passes the requests through to the strategy object:
class UserButSlightlyMoreAdvanced extends ActiveRecord implements ActiveRecordButSlightlyMoreAdvancedStrategy
{
private $_strategy;
public function useStrategy(ActiveRecordButSlightlyMoreAdvancedStrategy $s) {
$this->_strategy = $s;
}
public function someSlightlyMoreAdvancedFunction () {
return $this->_strategy->someSlightlyMoreAdvancedFunction():
}
}
Hope that helps.
The book says:
The decorator pattern can be used to extend (decorate) the
functionality of a certain object
I have a rabbit animal. And I want my rabbit to have, for example, reptile skin. Just want to decorate a common rabbit with reptile skin.
I have the code. First I have abstract class Animal with everythig that is common to any animal:
abstract class Animal {
abstract public function setSleep($hours);
abstract public function setEat($food);
abstract public function getSkinType();
/* and more methods which for sure will be implemented in any concrete animal */
}
I create class for my rabbit:
class Rabbit extends Animal {
private $rest;
private $stomach;
private $skinType = "hair";
public function setSleep($hours) {
$this->rest = $hours;
}
public function setFood($food) {
$this->stomach = $food;
}
public function getSkinType() {
return $this->$skinType;
}
}
Up to now everything is OK. Then I create abstract AnimalDecorator class which extends Animal:
abstract class AnimalDecorator extends Animal {
protected $animal;
public function __construct(Animal $animal) {
$this->animal = $animal;
}
}
And here the problem comes. Pay attention that AnimalDecorator also gets all the abstract methods from the Animal class (in this example just two but in real can have many more).
Then I create concrete ReptileSkinDecorator class which extends AnimalDecorator. It also has those the same two abstract methods from Animal:
class ReptileSkinDecorator extends AnimalDecorator {
public function getSkinColor() {
$skin = $this->animal->getSkinType();
$skin = "reptile";
return $skin;
}
}
And finaly I want to decorate my rabbit with reptile skin:
$reptileSkinRabbit = ReptileSkinDecorator(new Rabbit());
But I can't do this because I have two abstract methods in ReptileSkinDecorator class. They are:
abstract public function setSleep($hours);
abstract public function setEat($food);
So, instead of just re-decorating only skin I also have to re-decorate setSleep() and setEat(); methods. But I don't need to.
In all the book examples there is always ONLY ONE abstract method in Animal class. And of course it works then. But here I just made very simple real life example and tried to use the Decorator pattern and it doesn't work without implementing those abstract methods in ReptileSkinDecorator class.
It means that if I want to use my example I have to create a brand new rabbit and implement for it its own setSleep() and setEat() methods. OK, let it be. But then this brand new rabbit has the instance of commont Rabbit I passed to ReptileSkinDecorator:
$reptileSkinRabbit = ReptileSkinDecorator(new Rabbit());
I have one common rabbit instance with its own methods in the reptileSkinRabbit instance which in its turn has its own reptileSkinRabbit methods. I have rabbit in rabbit. But I think I don't have to have such possibility.
I don't understand the Decarator pattern right way. Kindly ask you to point on any mistakes in my example, in my understanding of this pattern.
Thank you.
Sounds like you're trying to force the use of a particular pattern that doesnt fit the problem. A decorator usually aggregates something additional (add braids to the hair), instead of completely changing it, like you're trying to do with the skin (hair to scales).
A Builder pattern, (whereby you specify how you want the object built) may fit the problem better. In your case, you want to build a rabbit built with a reptile skin. (where Im from, instead of reptile skin, it would have been funny to make a rabbit with horns and call it a jackalope :)
I think the use of a Builder (or any pattern) here may actually be overkill. Do you absolutely have to use a pattern for this particular problem? How about just defining the code as follows and leave patterns out of it for now:
class Animal {
private $rest;
private $stomach;
private $skinType;
public function setSleep($hours) {
$this->rest = $hours;
}
public function setFood($food) {
$this->stomach = $food;
}
public function setSkinType($skin) {
$this->skinType = $skin;
}
// define the other getters too
public function getSkinType() {
return $this->$skinType;
}
}
class Rabbit extends Animal {
public function __construct() {
$this->rest = "rabbitRest"; // put whatever a rabbit rest is
$this->stomach = "rabbitStomach"; // put whatever a rabbit stomach is
$this->skinType = "hair";
}
}
Disclaimer: Im a c++ guy and my php is really bad, Im sure this code has several problems, but I hope you get the idea.
So a Rabbit would just extend an Animal and set its properties accordingly. Then if somebody wanted a RabbitReptile, they could either extend Rabbit (probably overkill) or just make a Rabbit and set the skin type accordingly.
I don't know if I fully understood your question. This is how I read it:
Your decorator is not yet complete. As it shows, it's still abstract and incomplete:
abstract class AnimalDecorator extends Animal {
protected $animal;
public function __construct(Animal $animal) {
$this->animal = $animal;
}
}
If you want to make it easily work, you should decorate all methods as well, so you don't need to do that when you extend from AnimalDecorator. Here exemplary for two of the many methods:
abstract class AnimalDecorator extends Animal {
...
public function getSkinColor() {
return $this->animal->getSkinColor();
}
public function setSleep($hours) {
$this->animal->setSleep($hours);
}
...
After you've delegated all methods, you can override the ones you want to in your concrete decorator as you already do:
class ReptileSkinDecorator extends AnimalDecorator {
public function getSkinColor() {
return "reptile";
}
}
The Decorator pattern must delegate all members defined in its base class or implemented interface to the object it is extending. In other words the ReptileSkinDecorator's setSleep, setEat, and getSkinType methods must call the Rabbit's (or whatever other Animal descendant you choose to decorate with reptile skin) setSleep and setEat methods.
Also, I just noticed that in your example you are trying to alter the use of a method defined in the Animal base class (trying to define a skin type, which I assume you want to be immutable). You shouldn't really do that (hide object's immutable properties) with a Decorator pattern, because if the object were to be available outside of the scope of the decorator it would provide a different skin type (as you've defined it). Decorators don't generally change existing properties of the object they're decorating.
Perhaps a better example would be a HibernationDecorator. Since your base class has nothing related to hibernation you may want to make that decorator so that you can provide hibernation functionality for your rabbit. That is what Decorator is about - providing additional functionality not present in the base class or interface contract while still adhering to the base class' contract.
i would like to know if it is possible to have a function in PHP which returns an interface or a class which contains an interface?
i tried something like this, but it fails
<?php
//class for list of controllers for ACL
class Gestionale_Action_Helper_Crud extends Zend_Controller_Action_Helper_Abstract {
interface crud_controller
{
public function indexAction();
public function modificaAction();
public function cancellaAction();
public function creaAction();
}
public function getCrudInterface(){
return $this->crud_controller;
}
}
what i wanted to do, in zend framework, create an interface that crud controllers must implement, or even better if i could create an abstract controller and have them implement that
thank you
I'd suggest that you use Zend_Rest_Controller instead of creating your own interface.
Zend_Rest_Controller is an abstract class that defines five basic methods you need in a CRUD-controller: index, get, post, put, and delete.
Combined with Zend_Rest_Route it lets you create nice and clean RESTful application.
You can get more reading on Zend_Rest_Controller at http://weierophinney.net/matthew/archives/228-Building-RESTful-Services-with-Zend-Framework.html and http://techchorus.net/create-restful-applications-using-zend-framework
Just place the interface outside of any class (preferably in a different file) and let it be implemented by all your crud-controllers.
<?php
class GrudController implements CrudInterface
{
// ...
}
i'm not sure i get what it is you want to do, but i'm fairly certain you're asking the wrong question. if you simply want to make sure an object implements a certain interface, this is quite easy to do. lets say for example you have some helper method in a class which deals with a crud controller, you just specify the type in the argument list:
class crud_helper {
public function help(crud_controller $cc) {
$cc->indexAction();
}
}
now you can pass any object that is an instance of a class that implements crud_controller to the method help. but no other object.