I'm trying to make a parent class and child classes, lets say the parent class is called functionality and has functions like add(), validate(), and delete(), and the child classes are driver and passenger , each of the child classes inherit the functions but needs extra parameters and different logic for each inherited function, should I define the function but leave it blank? how is this helpful apart from extendibility?, and should I define a different constructor for each child class because they have different extra variables?
class functionality
class functionality{
protected $from;
protected $to;
protected $date;
protected $name;
public function add(){
}
public function validate(){
}
public function delete(){
}
}
class driver
class driver extends functionality {
private $gasMoney
function add($from, $to, $date, $name, $gasMoney){
//some logic and adding to database
}
}
class passenger
class passenger extends functionality {
private $seatPrefrance
function add($from, $to, $date, $name, $seatPreferance){
//different logic than class driver and
}
}
is this an acceptable approach? and how would I define a constructer? should I define it in the parent class? does the child classes inherit it and can add more to it?
You shouldn't use inheritance for this, it doesn't make sense.
The main idea is that other parts of your application can receive an object, and they don't care if it's a passenger or driver, they just get some instance of functionality and call add on it.
Another reason to use inheritance if you want to take advantage of some shared behavior, so you don't have to reimplement a method.
If arguments are different based on the sub-class, there's no way anything can do something with the generic functionality class, so this is pointless.
You also can't re-use the method, because you are clearly overriding the method for each case.
Think about driver and passenger. Are there parts in your application that need to work with both? What is their actual common functionality? Anything that's not common does not go in the base class.
I know this is probably a contrived example, but it also doesn't make sense to 'add' a passenger name to an existing passenger.
If you call your class 'passenger', I would expect that to represent a single passenger, not multiple.
Learn OOP as a tool, not a religion.
If you meet an inspiring preacher, they might teach you a whole new way of thinking about the world, and suddenly you see everything in a new light. You change your diet, your daily routine, and which TV programs you watch.
If you are given a new drill as a present, you might get some scrape wood to test it out a few times, but after that you'll wait until you need to put some shelves up. You won't work out how you can pour milk through a newly drilled hole in your breakfast counter.
The example you have come up with is trying to do OOP for OOP's sake. It doesn't make any sense, because you haven't actually got a problem you're trying to solve.
In particular, don't pull out the inheritance drill until you need it. Start off by looking for ways to encapsulate state in private properties and define behaviour that is more than just accessing that state. As a silly example, $driver->canLegallyDrive() method might internally check the $insurance and $alcoholLevel properties.
Even when you find logic you want to share, composition (just storing one object in a private property of another one) is often better than inheritance. Inheritance really comes into its own when you need polymorphism - multiple objects which look the same on the outside but behave differently on the inside. And even then, learning to use interfaces rather than base classes will unlock more potential.
Related
Sorry if this is a duplicate question or a common design principle, I have searched around but was unable to find any answers to this question. I'm probably just searching with the wrong keywords.
I have been looking at a popular library Sabre/Event (https://sabre.io/event/) and in the code there is a simple class/inheritance model that I am trying to understand:
The class EventEmitter implements EventEmitterInterface and uses EventEmitterTrait (see below for code).
There is a comment in EventEmitterTrait above the class which says:
* Using the trait + interface allows you to add EventEmitter capabilities
* without having to change your base-class.
I am trying to understand why this comment says this, and why it allows adding capabilities without changing the base class, and how that is different from just putting the routines into EventEmitter itself.
Couldn't you just extend EventEmitter and add capabilities in the derived class?
Simplified code:
// EventEmitter.php
class EventEmitter implements EventEmitterInterface {
use EventEmitterTrait;
}
// EventEmitterInterface.php
interface EventEmitterInterface {
// ... declares several function prototypes
}
// EventEmitterTrait.php
trait EventEmitterTrait {
// ... implements the routines declared in EventEmitterInterface
}
You're basically asking two questions here.
What are interfaces and why are they useful?
What are traits and why are they useful?
To understand why interfaces are useful you have to know a little about inheritance and OOP in general. If you've ever heard the term spaghetti code before (it's when you tend to write imperative code that's so tangled together you can hardly make sense of it) then you should liken that to the term lasagna code for OOP (that's when you extend a class to so many layers that it becomes difficult to understand which layer is doing what).
1. Interfaces
Interfaces diffuse some of this confusion by allow a class to implement a common set of methods without having to restrict the hierarchy of that class. we do not derive interfaces from a base class. We merely implement them into a given class.
A very clear and obvious example of that in PHP is DateTimeInterface. It provides a common set of methods which both DateTime and DateTimeImmutable will implement. It does not, however, tell those classes what the implementation is. A class is an implementation. An interface is just methods of a class sans implementation. However, since both things implement the same interface it's easy to test any class that implements that interface, since you know they will always have the same methods. So I know that both DateTime and DateTimeImmutable will implement the method format, which will accept a String as input and return a String, regardless of which class is implementing it. I could even write my own implementation of DateTime that implements DateTimeInterface and it is guaranteed to have that method with that same signature.
So imagine I wrote a method that accepts a DateTime object, and the method expects to run the format method on that object. If it doesn't care which class, specifically, is given to it, then that method could simply typehint its prototype as DateTimeInterface instead. Now anyone is free to implement DateTimeInterface in their own class, without having to extend from some base class, and provide my method with an object that's guaranteed to work the same way.
So in relation to your EventEmitter example, you can add the same capabilities of a class (like DateTime) to any class that might not even extend from DateTime, but as long as we know it implements the same interface, we know for sure it has the same methods with the same signatures. This would mean the same thing for EventEmitter.
2. Traits
Traits, unlike interfaces, actually can provide an implementation. They are also a form of horizontal inheritance, unlike the vertical inheritance of extending classes. Because two completely different class that do not derive from the same base class can use the same Trait. This is possible, because in PHP traits are basically just compiler-assisted copy and paste. Imagine, you literally copied the code inside of a trait and just pasted it into each class that uses it right before compile time. You'd get the same result. You're just injecting code into unrelated classes.
This is useful, because sometimes you have a method or set of methods that prove reusable in two distinct classes even though the rest of those classes have nothing else in common.
For example, imagine you are writing a CMS, where there is a Document class and a User class. Neither of these two classes are related in any meaningful way. They do very different things and it makes no sense for one of them to extend the other. However, they both share a particular behavior in common: flag() method that indicates the object has been flagged by a user for purposes of violating the Terms of Service.
trait FlagContent {
public function flag(Int $userId, String $reason): bool {
$this->flagged = true;
$this->byUserId = $userId;
$this->flagReason = $reason;
return $this->updateDatabase();
}
}
Now consider that perhaps your CMS has other content that's subject to being flagged, like a Image class, or a Video class, or even a Comment class. These classes are all typically unrelated. It probably wouldn't make much sense just to have a specific class for flagging content, especially if the properties of the relevant objects have to be passed around to this class to update the database, for example. It also doesn't make sense for them to derive from a base class (they're all completely unrelated to each other). It also doesn't make sense to rewrite this same code in every class, since it would easier to change it in one place instead of many.
So what seems to be most sensible here is to use a Trait.
So again, in relation to your EventEmitter example, they're giving you some traits you can reuse in your implementing class to basically make it easier to reuse the code without having to extend from a base class (horizontal inheritance).
Per Sabre's Event Emitter's docs on "Integration into other objects":
To add Emitter capabilities to any class, you can simply extend it.
If you cannot extend, because the class is already part of an existing
class hierarchy you can use the supplied trait.
So in this case, the idea is if you're using your own objects that already are part of a class hierarchy, you may simply implement the interface + use the trait, instead of extending the Emitter class (which you won't be able to).
The Integration into other objects documentation says:
If you cannot extend, because the class is already part of an existing class hierarchy you can use the supplied trait".
I understand it's a workaround when you already have an OOP design you don't want to alter and you want to add event capabilities. For example:
Model -> AppModel -> Customer
PHP doesn't have multiple inheritance so Customer can extend AppModel or Emitter but not both. If you implement the interface in Customer the code is not reusable elsewhere; if you implement in e.g. AppModel it's available everywhere, which might not be desirable.
With traits, you can write custom event code and cherry-pick where you reuse it.
This is an interesting question and I will try to give my take on it. As you asked,
What is the purpose of using traits to define functions for an interface ?
Traits basically gives you the ability to create some reusable code or functionality which can then be used any where in your code base. Now as it stands, PHP doesn't support multiple inheritance therefore traits and interfaces are there to solve that issue. The question here is why traits though ?? Well imagine a scenario like below,
class User
{
public function hasRatings()
{
// some how we want users to have ratings
}
public function hasBeenFavorited()
{
// other users can follow
}
public function name(){}
public function friends(){}
// and a few other methods
}
Now lets say that we have a post class which has the same logic as user and that can be achieved by having hasRatings() and hasBeenFavorited() methods. Now, one way would be to simply inherit from User Class.
class Post extends User
{
// Now we have access to the mentioned methods but we have inherited
// methods and properties which is not really needed here
}
Therefore, to solve this issue we can use traits.
trait UserActions
{
public function hasRatings()
{
// some how we want users to have ratings
}
public function hasBeenFavorited()
{
// other users can follow
}
}
Having that bit of logic we can now just use it any where in the code where ever it is required.
class User
{
use UserActions;
}
class Post
{
use UserActions;
}
Now lets say we have a report class where we want to generate certain report on the basis of user actions.
class Report
{
protected $user;
public function __construct(User $user)
{
$this->user = $user
}
public function generate()
{
return $this->user->hasRatings();
}
}
Now, what happens if i want to generate report for Post. The only way to achieve that would be to new up another report class i.e. maybe PostReport.. Can you see where I am getting at. Surely there could be another way, where i dont have to repeat myself. Thats where, interfaces or contracts come to place. Keeping that in mind, lets redefine our reports class and make it to accept a contract rather than concrete class which will always ensure that we have access to UserActions.
interface UserActionable
{
public function hasRatings();
public function hasBeenFavorited();
}
class Report
{
protected $actionable;
public function __construct(UserActionable $actionable)
{
$this->actionable = $actionable;
}
public function generate()
{
return $this->actionable->hasRatings();
}
}
//lets make our post and user implement the contract so we can pass them
// to report
class User implements UserActionable
{
uses UserActions;
}
class Post implements UserActionable
{
uses UserActions;
}
// Great now we can switch between user and post during run time to generate
// reports without changing the code base
$userReport = (new Report(new User))->generate();
$postReport = (new Report(new Post))->generate();
So in nutshell, interfaces and traits helps us to achieve design based on SOLID principles, much decoupled code and better composition. Hope that helps
For example, with a parent like this:
class Music {
private $timbre; // This?
protected $timbre; // Or this?
public function getTimbre(){
return $this->timbre;
}
}
In an inheriting child, is it OK from an OO point of view to access the member variable directly, or best to use the getters/setters?
class PostPunk extends Music {
public function doSomethingTimbreRelated(){
$punk_timbre = $this->getTimbre(); // This?
$punk_timbre = $this->timbre; // Or this?
// ... do something ...
}
}
I've read that keeping member variables private is better for encapsulation, but does that really matter in an inheritance hierarchy?
And I realize this is very trivial, but I sort of waffle back and forth to doing it both ways, so I'd like to settle in on one way
After a bit of research, now I understand that using getters/setters promotes loose coupling to the parent object, via encapsulation.
In a small project with few developers and simple classes, the benefits of this are not obvious.
However, imagine a large project with many inheriting classes, as well as external classes consuming getters/setters.
If, down the road, you need to modify or add some business logic to the value returned by the getter, you will have to rewire all of the inheritors to use the getters VS accessing the properties directly.
Same goes for the setter - perhaps you decide to add some data sanitization/validation. Directly accessing the properties will bypass these future improvements.
Analogy: Rather than letting your kid have free access to your purse/wallet, you are forcing her to ask you for money, then you decide what and how much to give her.
I have a class that is containing 10 methods. I always need to use one of those methods. Now I want to know, which approach is better?
class cls{
public function func1(){}
public function func2(){}
.
.
public function func10(){}
}
$obj = new cls;
$data = $obj->func3(); // it is random, it can be anything (func1, or func9 or ...)
OR
class cls{
public static function func1(){}
public static function func2(){}
.
.
public static function func10(){}
}
cls::func3(); // it is random, it can be anything (func1, or func9 or ...)
It is an interesting subject. I'm gonna give you a design oriented answer.
In my opinion, you should never use a static class/function in a good OOP architecture.
When you use static, this is to call a function without an instance of the class. The main reason is often to represent a service class which should not be instantiated many times.
I will give you 3 solutions (from the worst to the best) to achieve that:
Static
A static class (with only static functions) prevent you from using many OOP features like inheritance, interface implementation. If you really think of what is a static function, it is a function namespaced by the name of its class. You already have namespaces in PHP, so why add another layer?
Another big disadvantage is that you cannot define clear dependencies with your static class and the classes using it which is a bad thing for maintenability and scalability of your application.
Singleton
A singleton is a way to force a class to have only one instance:
<?php
class Singleton {
// Unique instance.
private static $instance = null;
// Private constructor prevent you from instancing the class with "new".
private function __construct() {
}
// Method to get the unique instance.
public static function getInstance() {
// Create the instance if it does not exist.
if (!isset(self::$instance)) {
self::$instance = new Singleton();
}
// Return the unique instance.
return self::$instance;
}
}
It is a better way because you can use inheritance, interfaces and your method will be called on an instanciated object. This means you can define contracts and use low coupling with the classes using it. However some people consider the singleton as an anti pattern especially because if you want to have 2 or more instances of your class with different input properties (like the classic example of the connection to 2 different databases) you cannot without a big refactoring of all your code using the singleton.
Service
A service is an instance of a standard class. It is a way to rationalize your code. This kind of architecture is called SOA (service oriented architecture). I give you an example:
If you want to add a method to sell a product in a store to a consumer and you have classes Product, Store and Consumer. Where should you instantiate this method? I can guarantee that if you think it is more logical in one of these three class today it could be anything else tomorrow. This leads to lots of duplications and a difficulty to find where is the code you are looking for. Instead, you can use a service class like a SaleHandler for example which will know how to manipulate your data classes.
It is a good idea to use a framework helping you to inject them into each others (dependency injection) in order to use them at their full potential. In the PHP community, you have a nice example of implementation of this in Symfony for instance.
To sum up:
If you do not have a framework, singletons are certainly an option even if I personally prefer a simple file where I make manual dependency injection.
If you have a framework, use its dependency injection feature to do that kind of thing.
You should not use static method (in OOP). If you need a static method in one of your class, this means you can create a new singleton/service containing this method and inject it to the instance of classes needing it.
The answer depends on what those methods do. If you're using them to mutate the state of the object at hand, you need to use the instance method calls. If they're independent functionality, then you can use the static versions, but then I'd question why they're part of a class at all.
So, there is a very basic difference in static methods.
To use static functions, you don't need to initialise the class as an object. For example, Math.pow(), here .pow() (in Java; but the explanation still holds) is a static method.
The general rule is to make the helper methods static.
So, for example, if you have a Math class, you wouldn't want to fill the garbage collector with classes which just help other, more important, classes.
You can use it as dynamic initializers, if you please!
Let's say you have a class RSAEncryptionHelper, now you can generally initialize it without any parameters and this will generate an object with a key size of (say) 512 bits; but you also have an overloaded object constructor which gets all of the properties from other classes:
$a = new RSAEncryptionHelper::fromPrimeSet(...);
Within a PHP class you can use class/methods/attributes: Abstract, Static, Private, Public, etc ...
The best way is to know how to mix them all within a class depending on the need, I will give you a basic example:
Within the Person class, you have private and public methods, but you have a method called "get_nationality" so this is a function that you need somewhere else but you do not have the Person class installed yet, so this method you put it as STATIC in this way you can invoke the "get_nationality" method without installing any Person class, this makes your business model more optimal and in turn now resources in the CPU.
Static functions are also very useful but
I usually make traits when I have to create functions that are independently related to a class.
I don't know if this approach is better or not but most times I found it useful.
Just sharing my approach here so that I can learn more about its pros and cons.
You can think a factory. You will give some materials, it will give you same output. Then you should use static function.
class ProductDetails
{
public static function getRow($id, PDO $pdo): SingleProduct
{
// this function will return an Object.
}
}
I am not defining the Object here. Just where you need a Single Product you can simply do that ProductDetails::getRow(10, $pdo);
Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
I have an application which defines certain actions on common object types.
For example, you can have forum post and images. For each forum post and image you can do the following actions: recommend, comment, rate.
I have currently defined a static class
class CoreObjectUtil
{
protected static $_objObjKey = null;
protected static $_objTypeKey = null;
public static function getComments (...) {...}
public static function getCommentsArray (...) {...}
public static function getRatings (...) {...}
public static function getRatingsArray (...) {...}
}
which is then subclassed like this
class ForumPostUtil extends CoreObjectUtil
{
protected static $_objObjKey = 'forumpost';
protected static $_objTypeKey = 'FP';
}
to provide the relevant functionality for forum posts. The 2 parameters suffice to let the generic code in CoreObjectUtil know what to do for each object type for which these functions are applicable.
To use these functions, I am calling the selectPostProcess() class in my instance classes like this:
public function selectPostProcess ($data)
{
$data = ForumPostUtil::mergeRatings ($data);
$data = ForumPostUtil::mergeComments ($data);
...
}
This works well and keeps the main code centralized in the CoreObjectUtil class with its subclasses providing the data setup to let the code in CoreObjectUtil know what to do.
An alternative approach would be to move the code from CoreObjectUtil into a base instance class which is then inherited in my instance classes. So rather than calling static methods from CoreObjectUtil I would be doing method calls like $this->getComments().
Either approach would work just fine from a functionality type point of view. I'm wondering however what ObjectOriented design guidelines and experienced ObjectOriented developers think of these two approaches. Which way of doing this is preferable and why?
I would appreciate any thoughts/insights on this matter. I can code either way without problem, but I'm having a tough time deciding which route to take.
That code you have now is, I think, the most procedural approach ever posing as OOP i.e what you have now is at the opposite side of OOP. Using the class keyword doesn't make it OOP.
First of all, you should forget about static, it's not that it's bad ot use but it's so easily abused that you really have to try first if the functionality can belong to an object modelling a domain concept (in your case forum related). Only if it doesn't make sense this way, you'll have it as a static method somewhere in a utility class.
Truth be told you have to redesign yur app around the OOP mindset, that is to define classes with behaviour which model a specific concept or process and which have only one responsaiblity. More over you should not mix things like business objects (object which model the forum concepts) with persistence concerns i.e don't put in the same object business functionality and database access. Use a separate class for accessing storage.
Use the Repository pattern to separate business layer from the persistence layer. Try not to mix together create/update functionality with querying IF it complicates things. Use a separate read model specifically for querying in that case.
The code you show us is about querying. You can have a simple DAO/Repository (call it what you want in this case) like this
class ThreadViewData
{
public $Id ;
public $Title;
public $Comments; //etc
}
class ThreadsQueryRepository
{
//we inject the db access object , this helps with testing
function _construct($db) { }
public function GetThread($id){ } //this returns a ThreadViewData
}
The postPRocess functionality is a service that can Merge Ratings and Comments. But maybe the merge functionality is more suitable to the Rating and Comment objects. I don't know the domain to actually give a valid suggestion.
Point is, you have to think in objects not in functions and right now all you have is functions.
Lets say I have a parent class
class parent { }
.....
This parent has three sub class
class child1 { }
class child2 { }
class child3 { }
and these child classes have further smaller parts like
class child1subpar1 { }
class child1subpar2 {
public function foo() {
echo "hi";
}
}
class child2subpar1 { }
class child2subpar2 { }
Now, how to sum this whole up like
class child1 extends child1subpar1, child1subpar2 { }
class child2 extends child2subpar1, childsubpar1 { }
class parent extends child1,child2,child3 { }
I need to execute the methods in its inherited classes and do something like this
$objparent = new parent;
$objparent -> foo();
No, but multiple inheritance is generally considered a bad practice. You should favor composition instead, so you just use instances of classes you wanted to inherit inside your class.
And now when I look into your question again, it's not even an inheritance issue, you should use composition. Maybe if you provided more detail what you expect that class to do, we should answer more accurately.
UPDATE:
You will need to create one method for each of these classes' method which you would want to use - it's called Facade design pattern. Or maybe you are not aware that you can call methods of inner objects like this:
$parent->subObject->subSubObject->wantedMethod();
Facade pattern:
http://en.wikipedia.org/wiki/Facade_pattern
in your case facade wouldn't be anything else than creating one class and define every single method you want to use, and inside that method calling any method of any of your inner instances. But i really don't see any benefit coming from this instead of calling
instances and methods hierarchically
Seems like you're really confused about OOP.
Parent class has no awareness of its children. If you want to execute a child class, you need to create its instance.
Multiple inheritance is also not allowed in PHP (as well as many other popular languages like Java).
It might be worth looking at aggregation - passing smaller sub classes into child or event parent class. also, you can use implement multiple interfaces to force subclasses to have a set of required methods.
What you're doing is really backwards. Inheritance is used to bestow common, shared functionality upon objects without code duplication. The inheritance goes from Parent to Child, everything the Parent can do, the Child can do as well, but it may do more (it extends the functionality of the parent).
class Parent {
function everyoneCanDoThis() { }
}
class Child extends Parent {
// I can implicitly use the everyoneCanDoThis() function
function onlyChildrenCanDoThis() { }
}
Since this is a top-down structure, the Parent should not rely on any specific Child. The Parent does not execute or call functions of a Child. Only you call functions of a Child, but these functions may be inherited from a Parent class.
You should put everything you want every object to be able to do in a Parent class. Specific functionality that's only relevant to a specific object goes into a Child.
Multiple inheritance is a different can of worms that's not possible in PHP, for good reasons. Come back to composition, as suggested elsewhere here, when you get the basics of inheritance. :)
Composition just means that you take several objects and hold references to them in another object. It has nothing to do with inheritance, as each of these objects may or may not inherit from a Parent class and they're still individual objects.
class ComposedObject {
private $part1 = null;
private $part2 = null;
public function __constructor() {
$this->part1 = new Part1();
$this->part2 = new Part2();
}
public function doTask() {
return $this->part1->doSomeTask();
}
public function doOtherTask() {
return $this->part2->doSomeOtherTask();
}
}
The ComposedObject does not have any functionality itself, inherited or otherwise. But it holds two other objects that each carry some functionality. The functionality in the "parts" may be exposed directly, so they're called like $composedObject->part1->doSomeTask(), they may be encapsulated as in the example, so they're called like $composedObject->doTask() and are internally delegated, or you may use some __call() trickery to automatically delegate functions called on the composed object to one of its "parts". This has the same problem as multiple inheritance though; if two "parts" both contain a method of the same name, which one do you call?
+1 to the others. You really have it backwards. Children ALWAYS extends their parents.
But there is even something that can act kind of like multiple inheritance in PHP: The Decorator Pattern.
I wrote an article about it on my blog here.
A class can implement more than one interface, which is a slightly different thing.
When you inherit from a parent, you get everything it has unless you choose to override something, plus you can extend it by adding additional more specific stuff, but the parent should not know anything about the child.
When you implement an interface, the interface defines methods but it doesn't implement them. It is up to you to implement it. Different classes can implement the interface methods however they want as long as they follow what the interface says.
Inheritance tends to be overused and leads to bad programs. Perhaps if you told us what problem you're trying to solve, one of us could suggest how you can structure your classes.
Using Interface in Php maybe solve the question.