It is OK to have methods depend one on each other inside a class, methods that are encapsulated together? Does this affect unit testing? or the term Unit is addressing to the whole class and not to the class own methods.
It is OK to do something like this:
<?php
class foo {
protected $baz;
protected $bar;
private function checkBaz($baz) {
// do some checking
}
private function checkBar($bar) {
// do some checking
}
public function setBaz($baz) {
if($this->checkBaz($baz)){
$this->baz = $baz;
}
}
public function setBar($bar) {
if($this->checkBar($bar)){
$this->bar = $bar;
}
}
}
I'm thinking if I want to use a bound method from this class to another class I have to rewrite the method a little bit, I was wandering if it is overhead to make methods somehow encapsulated like inserting functionality in to method parameters, Is this a common practice in OOP or should I stick to the thinking that a class is an encapsulation of high cohesion method and properties and see it like a whole reusable and testing Unit.
Yes, calling methods internally in a class is absolutely fine. In fact, it's encouraged. The mere presence of protected and private methods should be a dead giveaway. You can only call those from within the class, from somewhere that needs to be triggered by a public method, so yes, your example if perfectly in line with how those methods are supposed to be used.
The only thing that matters in general and in terms of unit testing is how the object as a whole behaves. Its public components are important, that's what other code interacts with and it's what other code observes. Whatever kinds of internal calls your object/class makes is perfectly up to its own discretion. If it helps your class structure to put certain code in separate methods and hide them from the outside world, so be it.
Yes, performing method calls like this is perfectly fine. They're marked as private so they remain encapsulated within your class and unexposed to the outside world.
If these method calls started to cause the class/object to deviate its main purpose, breaking single responsibility principle, then it would be worth looking at breaking the class into finer units and injecting this new dependency via dependency injection. An example of this would be if the checkBaz method was performing a database look-up.
In terms of unit testing, what you really want to do is program to an interface not implementation by creating an interface for your foo class and implementing it. This means whenever you program to it you're programming to a contract - allowing you to easily mock your IFoo implementation.
eg:
class Foo implements IFoo {
}
Your interface will look like this:
interface IFoo
{
public function setBaz($baz)
public function setBar($bar)
}
I would also recommend following the PEAR coding standard and make your class names uppercase first. Though if this is a decision made by you or your team then that's entirely your call.
There's nothing wrong with non-public methods. In fact, a class should only export the bare minimum of public methods to allow other classes to make use of its services. The more external classes know about the inner workings of your class, the more difficult it is to make changes to the inner workings of your class without upsetting external dependencies.
The non-public methods should be tested by being called indirectly. There should be a circumstance under which every method gets called eventually, even if it's through indirect calling (public method calls private method, etc). If a method is never executed in a unit test then that's a good indicator that it is in fact dead code and can be removed from the class altogether.
You can in theory directly test the protected methods of a class by subclassing it and elevating the protected methods to public, but that's not recommended because it exposes internal workings of your class and you don't really want to do that.
Related
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);
when I look through GitHub most projects define methods in the interface this way:
interface ExampleInterface
{
function getId();
}
my question now is why it is bad style to define the method visability in the Interface:
interface ExampleInterface
{
public function getId();
}
It makes the interface more strict but isn't that whats an interface used for?
what is the point of a private function in an interface? declaring public is redundant.
from TFM:
All methods declared in an interface must be public, this is the nature of an interface.
http://php.net/manual/en/language.oop5.interfaces.php
It is because an interface is a promise you give to the outside world of certain functionality. In your above example, whenever a class implements an interface, it is guaranteeing that the class will provide a method called getId to the outside world, irrespective of how it is implemented.
Hence, if you make a private promise, it is irrelevant as no one cares if there is a private method with some functionality, it is anyways not accessible by anyone else.
On the other hand, all methods in an interface are essentially public (since they are nothing but promises to the outside world) and hence you explicitly mentioning it as public is redundant.
Interfaces can only contain public methods, so the public is a bit redundant.
An interface can only have public members so there's no need to declare it. And these functions are meant to be inherited. Therefore; All methods declared in an interface must be public, that is its nature..
I can understand that private cannot work but protected as well?
I understand it is a "promise" to the outside world but if something implements an interface that method will stay protected therefore the same "promise" was still kept. It stated that there is function a, function b and also protected function c so from that we derive if I am not extending/implementing this then I can not have access to function c. Because it works the same when you read classes.
#AlphaMale Ok so what is the point of an interface then? It is used to create a "recipe" for a class right? So when you use it practically in code it will only be to implement and force methods. This becomes handy if methods are needed for your code to work and you don't want to force it to a specific class.
Lets say I have a to create Mailers, but I have to major processes where mails are needed but mailers will use different ways of constructing these mails. Now There needs to be a base send function that takes a message(any type) and a email address, but since the classes are in an open environment then it will be dangerous to leave this send function public and therefore we need it as a protected method. Now in the two Processes there are multiple mailers but each process shares the same way of constructing the method, so there is 2 abstract classes but now due to limited interfaces you now have to declare a third abstract class to contain this protected send function so that it can be extended as well otherwise you will have the same protected send function. If a new developer works on a completely new process and looks at the interface then the send function will never be forced. If we say it was possible to declare protected in an interface then outside if you check if something is an interface it will work the same as a class, you still can't access the the protected functions.
Private makes sense because then only the interface will know about these values and since an interface can't do anything this will be pointless.
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.
I am using php 5.3, and yes, there is a bug open for that, but some think this is not a bug, and this makes me wonder.
abstract class A{
private function bobo(array $in){
//do something
}
}
class B extends A{
private function bobo($shmoo,$shmaa){
//do something
}
}
This throws an error. Shouldn't inheritance ignore private methods?!
'Declaration of B::bobo() should be
compatible with that of A::bobo()'
Note that the bug report is slightly off, as PHP will log this message any time you have an error level of E_STRICT (or, more recently, regardless of your error level provided that you've set a custom error handler).
PHP's visibility rules clearly demonstrate that a child lacks the ability to see its parent's private members, which I doubt is all that surprising to anyone. If the child can't see its parent's methods, I don't understand how it can have a duty to obey their definitions.
I personally think that the bug being marked as bogus without any explanation of why it wasn't a real flaw (since it's non-obvious and I couldn't find any mention of it in the documentation) is a bit wrong, but yeah. That aside, I'm of the opinion line 2669 in zend_compile.c should actually read as follows:
} else if (child->prototype &&
(EG(error_reporting) & E_STRICT || EG(user_error_handler))) {
...which would avoid the error popping up when the parent's method was marked private. Given that you always have the option not logging E_STRICT though, and it doesn't really negatively impact anything, I suppose it's not really a big deal. I definitely don't see how it could have been intentional, but I'm not a PHP engine developer either.
I think there are two possibilities here. Either it's a bug or the documentation on PHP.net/manual is incorrect. Here are three sections of the PHP manual. First on inheritance:
Object Inheritance
Inheritance is a well-established
programming principle, and PHP makes
use of this principle in its object
model. This principle will affect the
way many classes and objects relate to
one another.
For example, when you extend a class,
the subclass inherits all of the
public and protected methods from the
parent class. Unless a class overrides
those methods, they will retain their
original functionality.
This is useful for defining and
abstracting functionality, and permits
the implementation of additional
functionality in similar objects
without the need to reimplement all of
the shared functionality.
And on abstract classes:
Class Abstraction
PHP 5 introduces abstract classes and methods. It is not allowed to create an instance
of a class that has been defined as abstract. Any class that contains at least one
abstract method must also be abstract. Methods defined as abstract simply declare the
method's signature they cannot define the implementation.
When inheriting from an abstract class, all methods marked abstract in the parent's
class declaration must be defined by the child; additionally, these methods must be
defined with the same (or a less restricted) visibility. For example, if the abstract
method is defined as protected, the function implementation must be defined as either
protected or public, but not private.
Finally, interfaces
Object Interfaces
Object interfaces allow you to create code which specifies which methods a class must
implement, without having to define how these methods are handled.
Interfaces are defined using the interface keyword, in the same way as a standard class,
but without any of the methods having their contents defined.
All methods declared in an interface must be public, this is the nature of an interface.
Suffice it to say: there is nothing in the documentation that mentions inheritance of private methods. If there is a relationship between the parent and child method signatures, then it is not documented and the bug report should at least show someone that the documentation needs to be updated (if the decision to have this behavior is intentional). And if there was not supposed to be a relationship, then well, it's a real bug.
That's my opinion...
In the bug report when you remove the interface there isn't an error.
That makes it "more" strange behavior because the interface is just empty.
I guess this is a design decision of the language. The Java language developers decided that this should be possible.
Private methods should certainly not be ignored by inheritance, consider for example Template method pattern where you may override behavior of a function in a derived class, but the parent class can still call that function
public class Parent {
public final function doThings() {
$this->initialize();
$this->customStuff();
$this->cleanup();
}
private final function initialize() {
// initialize processing
}
private final function cleanup() {
// cleanup processing
}
private function customStuff() {
// parent specific processing
}
}
public class Derived extends Parent {
private function customStuff() {
parent::customStuff();
// + derived class specific processing
}
}
Calling doThings method on Derived class instance will do parent specific processing, but because of possibility to override private methods it is still possible to take advantage of the extension point provided by the non-final parent class customStuff method.
EDIT: Also PHP method signature consists of only the method name as you can define a method taking zero parameters and still call it with multiple parameters. Function can then access the arguments using func_get_args function.
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...