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);
Related
I need to have method to get something from a database, but I don't understand the difference between static and normal functions in PHP.
Example code
class Item {
public static function getDetail($arg) {
$detail = $this->findProductId($arg);
return $detail;
}
private function findProductId($id) {
//find product_id in database where id = $arg
//return detail of product
}
}
and function outside of a class
function getDetail($arg) {
$detail = findProductId($arg);
return $detail;
}
If I use $item = Item::getDetail(15); and $item = getDetail(15); — they're the same.
What is the difference between static and function outside of a class?
If they are difference, How to use static function and function outside of a class? (I'd appreciate a really simple example.)
What are the performance properties between static and function outside of a class? Which is better?
1) What is difference between static function and normal function
While they are functions, I'd prefer to call them methods of a given class. One is a static method and the other is an instance method.
Static Method: $item = Item::getDetail(15);
Instance Method: $item = getDetail(15);
(refer to FuzzyTree's correct syntax above in the comments, however.)
2) How to use static function and normal function (if you simple exemplify is good)
Static means you do not have to instantiate (declare an object reference). That is, you can simply use the method. So, in your example, while the answer may be the same, the way you called that method/function is different, as you noted above.
In Java, for example, you have the Math class. It does not require instantiation to use, and in fact you cannot that I know of because its constructor is private. You can simply use a method by referencing the class and the method name you wish to use,
Math.pow(d1, d2); //no instantiation needed
in PHP this might be,
MyClass::pow(d1,d2); //no instantiation needed
Java: when to use static methods
3) Ask performance between static function and normal function. Which is better?
Better is a matter of your design. If you have to create an object every time you want to do the power of a number that will create more memoryusage than simply using the class directly. I do not have benchmark proof, but it seem logical since you are not handling the method the same way in memory. I do not think it will matter in real world unless you are doing a lot of complicated actions.
Performance of static methods vs instance methods
might also interest you.
I'm assuming you're asking about the difference between a static method:
class Item {
public static function getDetail($arg){}
}
And a function written outside of a class definition:
function getDetail($arg){}
Static methods should be used over functions written outside of a class for organizational reasons. In an application with many files, having Item::getDetails($arg) will give a hint of where that function is defined. Also, having just a function written outside of a class runs the risk of name collision, if you start writing many functions outside classes.
Especially if you are writing in the OOP style, you should be using static methods over functions outside of class definitions, but I think even in general, using static methods is the better way to go.
The difference about static and non static functions is a big answer and we have to look at Object Oriented Programming (OOP) in general.
OOP in general, as you should know, is about Classes and Object, a class describe and creates objects based of it's description.
If you tell the class to contain the function "A" the object will have a callable function "A" who will have access to the objects parameters.
However if you tell the class to have a static function you tell the class to have a callable function WITHOUT instantiate an object.
Confusing? Can be at first and hard to understand why it's sometimes needed when you take your first OOP steps. Static functions is a good way to share info about classes without the need to make an object.
An analgy would be:
Take the class Car and the object BMW.
the objects functions is about THE BMW, a static functions is about cars in general.
As of performance, it's not about performance at all, it's about design patterns. So performance-wise there is nothing to gain if the functions is static or non static.
1.Entire difference is, you don't get $this supplied inside the static function. If you try to use $this, you'll get a Fatal error:
Static functions are associated with the class, not an instance of the class
and You will get an E_strict warning in the second case.
2.Now static calling of non-static methods works but is deprecated. so use normal function.
3.Technically speaking Static methods and variables are useful when you want to share
information between objects of a class, or want to represent something
that's related to the class itself, not any particular object.
For some reason, PHP allows you to call non-static and static methods
interchangeably,So performance wise or in whatever way you may say just use a normal function.Static is not going to help you at all
The difference between static and non static is that you can access a static method without having an instance of the class.
$item = getDetail(15); shouldn't work because detDetail is a method in a class and not a function.
Performance of Static Methods
There used to be a big penalty when calling a static method - but it's fixed in 5.4.0. See http://www.micro-optimization.com/global-function-vs-static-method
From what the other guy said, if it uses more memory one way versus the other it will absolutely cause a performance difference. If you're using so much memory to the point of going into GC, it can cause queuing of processes due to backup, due to gc and take the whole system down potentially if it's an enterprise system with thousands of concurrent users. It may depend on the scale of the application.
We should never be of the opinion that a change in memory utilization is "minor". It's never minor in big systems...
Writing a PHP app and have several classes that only have static methods (no need for instance methods). An example of one is NumericValidator, which has methods like checkInteger($toCheck) which checks to make sure the argument you pass it is of type int, and checkGreaterThan($lOperand, $rOperand), which makes sure that the left operand is greater than the right operand, etc.
I know I could just throw each of these methods into a PHP file without putting them inside of a class, but I want to take an OOP approach here in case the API evolves to require instantiating NumericValidator.
But it does beg the question: how is a class with 100% static methods any different than have a class implement a singleton design pattern, where every reference used throughout the code base invokes the same instance?
For example, here is what my code looks like now:
public function doSomething($p_iNum)
{
if(!NumericValidator::checkInteger($p_iNum))
// throw IllegalArgumentException
// ...
}
But I could turn all of NumericValidator's static methods into non-static instance methods, forcing the programmer to instantiate it, and then implement a singleton design pattern so you can only ever reference 1 instance of it:
public function doSomething($p_iNum)
{
NumericValidator $nv = NumericValidator::getInstance();
if(!nv->checkInteger($p_iNum))
// throw IllegalArgumentException
// ...
}
Finally, my question: which is better and more in keeping with best practices? Are there performance considerations? How would either approach affect things like concurrency, or requests coming from multiple users?
I would use a static class in your example. The differentiator I would use is if there is any state of the properties of an instance you are trying to preserve across access. This is what a singleton is designed for. The static class gives organized access to methods in a namespace which is helpful for clarity in your code but it does not have any properties about itself.
So yes you can use a singleton but it would be bad form because there are no instance properties that you want to make available across page accesses.
Hope this helps.
Use Singleton instead of static class only if you going to pass instance of NumericValidator in variable to some function.
In PHP 5.3 you can get instance of static class:
class test
{
public static function instance()
{
print 'zz';
}
}
$z = new test;
$z->instance();
Don't care about concurrency requests in PHP, it's single threaded, each process executes own code.
Are there any reasons I should not create a final class with static methods to avoid that some internal functions are called?
final class ModuleGlobalFunctions {
static public function generateWord {
$result = '';
while (strlen($result) < 12) {
$result = self::generateSyllable();
}
return $result
}
static private function generateSyllable() {
// Generates a random syllable.
// …
}
}
$word = ModuleGlobalFunctions::generateWord();
// It raises an error.
$syllable = ModuleGlobalFunctions::generateSyllable();
Creating a class to shield off private functions is a good idea. This way, a public method in the class can call a private method, without making the private method callable from outside the class.
Making a class final is also a good idea, as this indicates that the class has not been designed with overloading in mind, and makes the class simpler.
Making the class static is a bad idea, because it tightly couples the caller to the class. If you call Test::generateWord(), this will always use the Test class. However, if you use $test->generateWord(), you can pass in another class, which creates other words. This makes it easier to change the software and easier to unit test it.
Well, personally, I would recommend using classes to group similar logic. So in your case (the example you provided), it's a good idea.
As for final, it's a toss up. I prefer to use abstract to prevent instantiation (since PHP doesn't support static classes). If you do use final, I would suggest adding a private constructor to prevent instantiation: private function __construct() {}...
Personally, I like the concept of keeping it static. The reason is three fold. First, it's easier on memory (since there are no instances to keep track of). Second, it's faster (A static method call is faster than an instance method call). Third, and more importantly, it makes sense. Instances have a state (that's why they are instances). Does your class need a state? If so, then use an instance. If not, that's exactly what static classes are meant for...
As for passing an instance as Sjoerd mentions, you can do that with static classes (and actually be less tightly coupled than with instances). Here's the reason. Unless you require (and check for) an interface or inheritance, you have no idea if the object actually implements the method generateWord(). But, if you pass in a callback, it doesn't matter how the method is accessed (or its underlying construction), all that matters is that it has the same (or similar) syntax (with respect to parameters and return values). Now, interfaces are a better solution to this (since it enforces the interface), but they require pretty deep understanding of OOP to get the design right. In a pinch, a callback will work quite fine for that case...
I need some advise on my PHP code organisation.
I need classes where I can store different functions, and I need access to those classes in different parts of my project. Making an object of this classes each time is too sadly, so I've found a two ways have to solve it.
First is to use static methods, like
class car {
public static $wheels_count = 4;
public static function change_wheels_count($new_count) {
car::$wheels_count = $new_count;
} }
Second is to use singleton pattern:
class Example {
// Hold an instance of the class
private static $instance;
// The singleton method
public static function singleton()
{
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
} }
But author of the article about singletons said, that if I have too much singletons in my code I should reconstruct it. But I need a lot of such classes.
Can anybody explain pros and cons of each way? Which is mostly used? Are there more beautiful ways?
See this excellent post:
Singleton Pattern vs Static Classes
More Resources:
How Bad Are Singletons?
Static DB class vs DB singleton object
When you say that you need to use a class of some sort to store functions, I am presuming that you'd normally be fine using plain functions but you do not want to pollute the global scope. This problem you will run into all the time in PHP.
If you are lucky to be working with PHP 5.3 you can use namespaces to pull the functions out of the global scope. Effectively, namespaces serve as a convenient way to auto-complete the prefixes you would normally have on functions to try and ensure their uniqueness. Because of this primitive implementation, there is no access control available for namespaces. If you wish to design an interface, you are out of luck, as all functions are globally accessible.
In this case, use a static class. No, it is certainly not the most beautiful solution but it is literally the best PHP can offer. With a static class you can effectively both prefix your functions for uniqueness and use access control.
Singletons are an object-oriented concept that solve a different problem. If your original design involves no objects, don't introduce them now.
That said, you have a function called change_wheels_count(). This function has a notion of state, and whenever you need state you need an object. I do not know if your code was just a quick example or your actual situation. If it was your actual situation, I would say you need neither a static class or a singleton.
Are constructor methods in interfaces bad?
Why do people think that anybody wants to instantiate the interface?
What we want to do is to force implementers to implement the constructor, just like other interface methods.
An interface is like a contract. Let's say I have an interface Queue, and I want to make sure that implementers create a constructor with one argument, which creates a singleton queue (A new queue with just that element). Why should that not be part of the contract? With at least Java interfaces, that cannot be specified.
They are bad in that they serve no purpose. At its core, an interface is simply a data passing contract. There is no implemenation attached with an interface and hence there is nothing to initialize and no need for a constructor.
If you need some sort of initialization your much better off using an abstract class.
First off, I disagree that interface is just a data passing contract. If that were true you would be allowed to define properties in an interface.
I wouldn't exactly think it's weird to do something like:
interface IDBConnection
{
function __construct( $connectionString );
function executeNonQuery( $commandText, $paramters=null);
function executeScalar( $commandText, $paramters=null);
function executeSingle( $commandText, $paramters=null);
function executeArray( $commandText, $paramters=null);
}
This would enable you to create instances of third party classes for data access based on simple reflection instead of just being a data contract.
I'm pretty sure that this isn't the best example, I'd go for an abstract base class here in the real world, but I'm also pretty sure that there are perfectly valid reasons for defining a constructor methods' contract in an interface that I haven't thought of.
I haven't seen it done, but i wouldn't think it to be weird or bad.
Although interfaces can't have constructors in most languages, the Factory pattern provides a contract for constructing objects, similar to an interface. Take a look at that.
Whether or not they are bad, I am not aware of any language that has the ability to specify a constructor on an interface.
That being said, however, I personally do not believe that the constructor of an object is part of that object's interface and as such adding a constructor to an interface would inhibit the natural flexibility that interfaces afford.
You have to instantiate immutable polymorphic objects sometime via their constructor that requires parameters and you may need that constructor in the interface for the exact same reasons you may need the other public methods in the interface, for example…
Say you have to instantiate a polymorphic object, its class implementing your interface and being supplied by the client code. As a dumb but simple scenario let's say this object is a value object and as such should be immutable, which mean the object's state should be valid from the moment it's instantiated…
$immutablePolymorphe = $userConfig['immutable_polymorphe_class'];
$immutablePolymorphe = new $immutablePolymorphe($state);
// Then do something with that polymorphe...
So what if you don't define the constructor with its parameter in the interface? Hence the reason why I believe a constructor in an interface can be as much legitimate as any other public method in an interface…
I don't know why Google sent me here :)
But the question is an interesting one, and I have seen some people in many projects defining the constructor in the interface. But I really think it is a useless restriction. No client of this class can call __construct.
And defining it in the interface does not restrict any behavior, still I can implement it as I wish, I can even have an empty function like:
...
function __construct(string $name) {}
...
Then what is the benefit from it? It just blocks you from doing polymorphism, without any single benefit.
So if you have:
<?php
interface Shape {
function __construct(int $width, int $height);
public function getArea();
}
class Square implements Shape {
public function __construct(int $width, int $height) {...}
public function getArea(){...}
}
// This will throw an exception because it does not implement the correct constructor signature!
class Circle implements Shape {
public function __construct($radius) {...}
public function getArea(){...}
}
And even if you want to extend Square, then you have to implement the same constructor!.
And there is an example in the answers like:
You have to instantiate immutable polymorphic objects...
and example looks like:
$immutablePolymorphe = $userConfig['immutable_polymorphe_class'];
$immutablePolymorphe = new $immutablePolymorphe($state);
// Then do something with that polymorphe...
That is smart thinking, but only if you can restrict the strings in the $userConfig array to be of a specific interface! Which is not possible at least to my knowledge.
So bottom line :D I think having __construct in the interface is bad and blocks you from evolving your software, and it encourages you to have bad workarounds.