Let's say
a) I have trait and use it in another class. I know how that works.
b) I have normal random class called Helper and I have functions in that Helper class and I include that class in another class. I can use those helper class's functions in another class by using
Helper::method()
if method is static or use new keyword and use the method like
$helper->method().
c) I can have just a PHP file and functions in it, no class at all. I can include it in another class and just use it just this way:
method()
d) I can have a class, and then another class can extend it and have its functions, but this way is bad, as I can't extend two classes at the same time.
Why is using trait the best way compared to b) and c) solutions?
Why is using trait the best way compared to b) and c) solutions ?
Each of your examples are a good solution for different developments.
Helper::method();
Helper->method();
You have a function you will use in many Classes. The function is relatively generic.
Then put it on a Helper class, and if possible, set it static
method();
That's another question: procedural or oriented object development ? Then it depends on the context.
Trait{ ... }
Some specific (or not) functions which need to be present on different classes ?
Or you want to sort your functions by their use, or something else (I do that a lot when I have too many functions in one class)
But remember that there are some conventions to follow when you develop.
If you want to share your code (GitHub for example), it's better to stick to them (not really an obligation but well...).
To conclude, it depend on whant you want to do, on the context of your development.
There is no method better than the others.
Related
I've been reading up about PHP's traits. Specifically I came across this article. They probide an example involving objects that need to implement a shareable interface. The following argument is presented:
Does it make sense to duplicate the share() method in every class that implements the Shareable interface?
No.
Does it make sense to have an AbstractShare class that objects who implement the Shareable interface extend?
No.
Does it make sense to have the share() method implemented as part of an AbstractEntity class, but then blocked out for the Message object?
No.
Does it make sense to implement a ShareableTrait that fulfils the interface contract and can therefore be easily added to only objects that require it?
Yes!
I can understand the first and third points. But the second one confuses me. What exactly is wrong with having an abstract class called AbstractShareable or something like that which contains the functionality to share something, and then extending from it?
An interface is specifically designed to create reliable, well, interfaces, independent of the implementing class. Meaning:
function (Shareable $sharable) {
$shareable->share();
}
You can be assured that this code will always work (any object being passed in having a share() method), due to your interface declaration.
You can achieve the same thing using a class hierarchy; i.e. if you require a certain class, you can be sure that all of its children will also have the same methods the parent has. But: this imposes a strict class hierarchy on your classes. All classes have to extend one specific base class. And they can only extend that one specific class. You couldn't use a class hierarchy for both an AbstractSharable and an AbstractLoggable, say. That's why the class hierarchy solution is too inflexible. It would only allow you to implement one "trait". Or you'd have to mash all your various "traits" together into the same base class. Then you have a giant monolithic base class.
Separating characteristics into small individual interfaces keeps your code simple and flexible. Traits provide a flexible implementation analogue to an interface's specification.
I need to develop a small CMS using PHP, and right now I'm trying to figure out the structure.
The CMS will be generated using a set of functions. Things like database functions, caching thingies, internationalization and stuff like this.
I was thinking to do it like this:
make the functions non-static methods part of a big "site" class; that way I could run multiple instances of that class. Not sure I would need to do that though..
or split the functions into separate classes with static methods
The main problem here is that the CMS should be able to manage multiple small sites, not just one. So either I make all methods static and add a "site switch" function, or make them normal objects which I instantiate based on the site which I want to manage
Which of these would be the best option?
Static methods are generally bad practice. They introduce a lot of potential issues.
1) They introduce hidden dependencies. Code which arbitrarily calls foo::bar() has a dependency on foo and cannot run without foo being defined. The object using foo::bar() will construct correctly but won't be usable if foo is not defined.
2) Statics are globals. Global state is very bad, anything can change the code and its state is unknown. You sacrifice the power and control achieved by OOP encapsulation by using static methods.
3) It's impossible to substitute the functions for a different version
4) It makes unit testing impossible.
For more detailed information and code examples, see this article and this article
I'd definitely suggest using static classes for this job. Going this route will create a pseudo namespace for all of your functions so you don't have to worry about conflicting function names, etc, and it also prevents you from having to pass around an instance of your helper class just to call one of your helper functions.
This might be a stupid question but I have to ask:
I have a big group of related functions for a project I am doing. The functions need to access a few global variables, so I was thinking about putting them into a class and loading the class as needed. I suppose my other option is to just include them as unrelated functions in an included PHP file, but putting them into 1 class seems to make sense. Is this an acceptable practice? I have worked with people who did this but it always seemed to not quite be in the spirit of good OOP practices because the classes were almost never instantiated but the functions were still called. Or maybe I'm over thinking it.
Any input would be awesome, thanks a bunch.
A class does make the most sense. Whenever you can eliminate global variables, it is a good thing. Whether the class is instantiated or a static helper usually depends on the context. However, for future unit testing, instantiations allow dependency injection.
According to http://en.wikipedia.org/wiki/Class_%28computer_programming%29, a class defines constituent members which enable class instances to have state and behavior. If you will be providing only behavior (functions) and not state (properties), you should include your functions in an include file and forgo the overhead of a class.
Correct me if I'm wrong but this seems like you should create a class that acts as a static service, where no explicit instantiation is needed of the class, yet you will still call the methods contained within this class.
Now, if you're thinking of storing those global variables in the class, obviously that's no longer a static class because there would have to be some sort of lifetime for the object, and at which point you'd have to instantiate the class first and then make calls to those methods.
Regardless, if they're all related functions working on the same data, it certainly makes sense to group them within their own class.
I've faced a situation when I want to extend two parent classes, but php does not allow this.
Why I can't extend more than one class, but can implement more than one interface. What's wrong with extending many classes?
It seemed to me like a pretty obvious thing, until I got parse errors.
Is it a bad practice? If so, what are the alternatives?
Is it possible in other languages?
Why multiple inheritance is forbidden in some/most programming languages is argued with the diamond problem http://en.wikipedia.org/wiki/Diamond_problem.
Put simple if you have a car that can swim and drive because it inherits from vehicle and boat what happens on execution of the move function!?
Try using interfaces and follow the Strategy pattern or State pattern.
You're probably looking for: Multiple Inheritance in PHP.
It seems to be possible in Python.
Take a look at Can I extend a class using more than 1 class in PHP?
Is it a bad practice? If so, what are alternatives?
Unless the language is specifically designed for it, yes. Consider, you have two classes, A and B. Both classes provide a public method foo() which have identical signatures (not hard in PHP). Now, you make a class C which extends both A and B.
Now, you call C.foo(). Without explicit instructions, how does the interpreter know which version of foo() to call?
It's not supported by PHP. It can however be simulated using runkit, APD or by just overriding __call and __get to simulate inheritance from multiple classes. Symfony (and I seldomly recommand that) also provides "sfMixin" or "sfMixer" for multiple inheritance.
Separate classes implementing the same method is not a good argument against multiple inheritance, as currently multiple interfaces can be implemented. You just can't implement two interfaces with the same method. Quote from http://www.php.net/manual/en/language.oop5.interfaces.php: "A class cannot implement two interfaces that share function names, since it would cause ambiguity."
I know this question is 2 years old but I've only just had the same problem. My work-around is this: if you have one regular class and two abstracts and want to extend both, e.g abstract class AbstractOne and abstract class AbstractTwo, you can say:
abstract class AbstractOne extends AbstractTwo {
}
Then add to the main class like this:
class MyMainClass extends AbstractOne {
}
This way, it inherits both AbstractOne and AbstractTwo.
at my working place (php only) we have a base class for database abstraction. When you want to add a new database table to the base layer, you have to create a subclass of this base class and override some methods to define individual behaviour for using this table. The normal behaviour should stay the same.
Now I have seen many new programmers at our company, who just override the method for the default behaviour. Some are so "nice" to put in all the default behaviour and just add there individual stuff where they like it, others kill themself trying to use the baseclass and their inheritor.
My first thought to solve this problem, was thinking about abstract methods that should be overriden by inheriting classes. But beside other arguments against abstract methods, "abstract" just does not show why the baseclass can't be used by its own and why these function should be overriden.
After some googling around I didn't find a good answer to implementing "real" virtual functions in php (just that there is a virtual function, that nearly kills all hope of a concrete implementation).
So, what would you do with this matter?
In PHP all public and protected functions are "virtual". You can prevent functions from being overriden by prepending the final keyword. (Or by making them private, but this is probably a bad idea).
In the design of the baseclass I would think of behaviors that subclasses would want to affect.
I would for example create empty functions like before_update() and after_insert().
function after_insert() {
// Virtual
}
Which the baseclass will call when an update/insert event occurs.
Maybe an is_valid() function which always returns true in the baseclass, and use the commentblock to describe what the consequences are when a subclass return false.
Hopefully this would give you some inspiration.
You can always use the "final" keyword to prevent some of the classes functions from being overridden if people are using the class in the wrong way.
It sounds to me like they are unable to acheive certain functionality hence overriding the methods. You may need to take a look at the design of your classes.
Without an example of the implementation of your base class, it's hard to give concrete info. But a few things come to mind:
Database abstraction is complex stuff to begin with. I understand that you want to keep it lean, clean and mean, but I think it's pretty darn difficult. You really have to take a thorough look at the specs of different DB engines to see what parts are general and what parts need specialization. Also; are you sure you don't have DB abstraction mixed up with the Table Data Gateway pattern, as you are talking about adding DB tables by extending the base class?
The methods of your current base class might be doing too much and/or are not general enough to begin with, if the extended classes are bending over backwards too keep it clean. Maybe you should break the base class interface methods up in smaller protected methods that are general enough to be reused in the overriding methods of the extended classes? Or vice versa: maybe you should have hooks to overridable methods in your interface methods.
Following from point 2: What's wrong with having an abstract class with some general implemented methods, and let your vanilla class (your base class) and other classes inherit from that?
Lastly, maybe you should just enforce an interface to be implemented, in stead of extending the base class?