Prior to PHP 5.3 I used to name interfaces/abstract classes like this:
abstract class Framework_Package_Subpackage_Abstract {}
Framework/Package/Subpackage/Abstract.php
interface Framework_Package_Subpackage_Interface {}
Framework/Package/Subpackage/Interface.php
Now with PHP 5.3 and using namespaces I can't use my convention anymore, because interface and abstract are reserved keywords.
namespace Framework\Package\Subpackage;
abstract class Abstract {}
Framework/Package/Subpackage/Abstract.php
namespace Framework\Package\Subpackage;
interface Interface {}
Framework/Package/Subpackage/Interface.php
So, what should I name my classes/interfaces like?
A current coding guide "PSR-2" basically suggests you drop the interface down one directory and combine the name.
eg:
File \Vendor\Foo\Interface.php ===> \Vendor\FooInterface.php.
and the use stament eg:
use \Vendor\Foo\Interface; ===> use\Vendor\FooInterface;
see: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
About this question (Abstract and Interface), you might have a look at the post "Migrating OOP Libraries and Frameworks to PHP 5.3" on Matthew Weier O'Phinney's blog -- it's about Zend Framework, and how they could solve that problem in 2.0.
One of the things they note is :
In other OOP languages, such as
Python, C#, interfaces are denoted by
prefixing the interface with a capital
'I'; in the example above, we would
then have Zend::View::IView.
So, in your example, you would have something like this, I guess :
namespace Framework\Package\Subpackage;
abstract class ASubpackage {}
Framework/Package/Subpackage/ASubpackage.php
namespace Framework\Package\Subpackage;
interface ISubpackage {}
Framework/Package/Subpackage/ISubpackage.php
What do you think about that ?
(I have not tested this way, but it doesn't look like a bad idea ? )
SubpackageAbstract,
SubpackageInterface
I personally would recommend avoiding any usage of Hungarian Notation, and consider following the Java standard for interface names; that is, they're named descriptively just like any other class. See this SO question for a discussion of the ins and outs of Hungarian notation.
A good example of using generic, descriptive names indicative of functionality or behavior can be found in PHP's own SPL, like: "Countable", "Iterator", "ArrayObject".
You could also do something like this:
src/Chess/Piece.php
<?php
namespace \Chess;
abstract class Piece implements \Chess\PieceInterface {}
src/Chess/PieceInterface.php:
<?php
namespace \Chess;
interface PieceInterface {}
src/Chess/Piece/Pawn.php:
<?php
namespace \Chess\Piece;
class Pawn extends \Chess\Piece {}
Here's how I would setup autoloading in composer.json
{
"autoload": {
"psr-0": {
"": "src/"
}
}
}
Honestly, I believe the Hungarian notation was introduced with C#, because there is not "extends" and "implements" keyword like in Java. So to differentiate the convention became to call it IView. In Java, the interface would be called View alone, and implementations would be called DefaultViewImpl, SmartyViewImpl or something like that. Since, PHP does have extends and implements keywords, it makes sense to use the Java convention.
I have heard the argument that the Hungarian notation does lend it self to making the API elements identifiable just by looking at the class names. In that case I would call it either IView or AbstractView.
In my opinion, the best way to solve this, is by simply appending Class to your classnames.
namespace Framework\Package\Subpackage;
abstract class AbstractClass {}
Framework/Package/Subpackage/AbstractClass.php
namespace Framework\Package\Subpackage;
interface InterfaceClass {}
Framework/Package/Subpackage/InterfaceClass.php
note that this is still not perfect (however, works perfectly) but i keeps the code similar to the original idea ;)
Related
Let's say I have a class:
class Person
{
public function doSeomthing()
{
// ...
}
}
I want to extend this class to add extra functionality, using my own namespace. Is it a good or bad idea to use the same class name? For example:
namespace Custom;
class Person extends \Person
{
public function doSomethingElse()
{
// ...
}
}
I'm particularly interested as to what PSR standards might feel about this.
Using the same class names, or Name collisions is one of the problems that namespaces are specifically designed to solve.. http://www.php.net/manual/en/language.namespaces.rationale.php
In the PHP world, namespaces are designed to solve two problems that authors
of libraries and applications encounter when creating re-usable code elements
such as classes or functions:
1.Name collisions between code you create, and internal PHP
classes/functions/constants or third-party classes/functions/constants.
2. Ability to alias (or shorten) Extra_Long_Names designed to alleviate
the first problem, improving readability of source code.
Should an abstract class always be prefixed with Abstract and suffixed with Interface (when it's an interface)? Is there any standard naming convention, similar to PSR-0 for folder structure/namespaces, but for classes?
It seems redundant as the language has literal keywords for this very purpose.
abstract class AbstractFoo {}
interface InterfaceFoo {}
trait TraitFoo {}
The PHP-FIG project indeed suggests a naming convention via the PSR Naming Convention "ByLaw" https://www.php-fig.org/bylaws/psr-naming-conventions/
It states:
Interfaces MUST be suffixed by Interface: e.g. Psr\Foo\BarInterface
Abstract classes MUST be prefixed by Abstract: e.g. Psr\Foo\AbstractBar
Traits MUST be suffixed by Trait: e.g. Psr\Foo\BarTrait
These conventions are generally followed in packages
Although there's not any convention, I think it is a good practice using Abstract prefix and Interface suffix for respective components. It helps to understand better the code at a glance, IMO.
There isn't a convention for this; especially in PHP. This can all be organized however you'd like.
With the additions of namespaces in PHP 5.3, I don't see the need to add Abstract or Interface prefixes/suffixes to the actual class names.
Just name things as they are!
Going against most of the other answers, I would suggest that it's better not to add a prefix or postfix to the class. The language has literal keywords such as abstract, interface, class, final for this purpose.
The following actually breaks clean code principals:
abstract class AbstractPerson
{
// ...
}
Similar thinking to "comments are generally bad, as it suggests the code is not easily readable". If your classes, inheritance and their contracts are engineered in a clear and readable fashion that makes sense, there is no need for prefixing.
Behavioural design
It's usually possible to name things in a manner that reflects their behaviour. For example in a logging subsystem:
interface Loggable
{
public function getLog(): string;
}
trait WritesLogs
{
public function writeLog(): void
{
file_put_contents("logs.txt", $this->getLog());
}
}
abstract class Event implements Loggable
{
use WritesLogs;
public function asLog(): string
{
return "{$this->getName()} at {$this->created_at}";
}
abstract public function getName(): string;
}
class FooCreated extends Event
{
public function getName(): string
{
return 'Foo was created';
}
}
Naming your abstract classes and interface by using:
Abstract*
*Interface
Will keep your codebase clean, nice and obvious to your team what are the prototypes, what are the contracts and what are the concrete implementations.
Naming conventions are here to increase our productivity in any circumstance, so "name as you like" is far from good idea.
Even though FIG group does not propose naming convention for abstract classes and interfaces - if you examine major open source PHP projects, you will see that almost all of them uses this convention.
Conventions are what you see them like: the language itself doesn’t force any conventions other than those that makes the parser able to read your code. Basically, you should have conventions set up on your own for a particular project, or better, for all of your projects. However, working in teams of different people could lead to conventions not being followed, it really depends on the programmers.
From my experience, I would suggest following something like "design-by-contract". Name your contracts (interfaces) like you would name your implementation class, and then give your implementation a more specific name (or fallback to MyContractNameImpl, known mostly from Java I guess). Also, many modern IDEs know whether your class is an interface or abstract, so there is really no need to put that in it’s name. I also find contracts named like "IMyContract" not really good, for the same reasons.
I have class named Controller_Home. It should inherit from Controller_Permissions and Controller_Template. Any class prefixed with Controller_ must inherit from Controller class.
If multiple inheritance would be supported in PHP (my case), I could do like this:
class Controller_Home extends Controller_Permissions, Controller_Template {
And Controller_Permissions, Controller_Template:
Controller_Permissions extends Controller {
Controller_Template extends Controller {
Now I need to do something like this:
class Controller_Home extends Controller_Template {
class Controller_Permissions extends Controller_Template {
Controller_Template extends Controller {
Okay, it works!
Now I need to use Controller_Template without permissions (in Controller_Permissions).
How to do it without duplicating code? I don't want another class Controller_TemplateWithoutPermissions.
Controllers, templates and permissions is just for example.
The common alternative to multiple inheritance is to use composition. This makes the relationship a "has a" as opposed to an "is a" relationship. Ie in your example above you might have ControllerHome inherit from ControllerTemplate but hold some ControllerPermissions as a variable. This way ControllerHome is a ControllerTemplate and has a ControllerPermissions.
You could use Traits in this situation.
Traits are similar to mixins, but whereas mixins can be composed only using the inheritance operation, traits offer a much wider selection of operations, including symmetric sum, method exclusion, and aliasing. A Trait differs from an abstract type in that it provides implementations of its methods, not just type signatures.
Traits is available in PHP 5.4 and is common in Scala.
There's nothing pretty about that at all. All of your classes are very tightly coupled together. Defining, and then implementing interfaces on the objects, and using aggregation to build up the 'with permissions' and 'without permissions' types is a cleaner, and 'prettier' solution. It also allows for IoC (which breaks encapsulation if you're a staunch SOLID person), which gives you better unit testing scenarios, and allows for the use of a DI container.
Just a quick question on your preference of using PHP namespaces or class prefixing.
<?php
// ----- namespace -----
use My\Namespace;
$object = new Namespace\Object;
// ----- prefix with PR -----
$object = new PF_Object; //or
$object = new PFObject;
Which do developers prefer? I know why the use of namespaces can bring great advantage to applications, but also can quite a hindrance in PHP in my own opinion.
Thanks!
Combine use with an alias:
use My\Namespace\Foo as Foo;
$object = new Foo;
It's also useful like so:
namespace My\Debug\Stuff;
use My\Production\Stuff\Foo as BaseFoo;
class Foo extends BaseFoo {}
Why would you consider namespaces a hindrance?
class prefixing seemed to me like a sort of a hack to implement 'in code' a mecanism to implement namespaces.
Newer code now has the option to use a native built-in way of handling namespaces. This is a much cleaner approach, in my very humble opinion.
Consider this popular yet eye-opening example that allows legacy code to use namespace:
// Using native namespace features to shorten class prefixes
<?php
use Sabre_DAV_Auth_Backend_PDO as AuthBackend;
use Zend_Controller_Action_Helper_AutoComplete_Abstract as AutoComplete;
$backend = new AuthBackend();
?>
Clearly, there's no need to use the underscore character to fake namespaces any more, so I suppose the question boils down to "is it a good idea to use underscore characters in class names".
IMO, the answer is no, firstly because it looks ugly (IMO) and secondly because some older class loaders could get confused by a class name that includes an underscore.
well
if you are running PHP 5.2.X you only have the option 2
but if you are running PHP 5.3.Xyou could use both.
In my case running PHP 5.3.X I would use the feature that the new version of the language offers. To make an analogy is likely be running JAVA 1.6 and don't use generics (or sort of)
Do you think it's a good practice to differentiate abstract from non-abstract classes by giving their name a prefix or a suffix? What are the most common practices when it comes to that?
Here are a few "formats" I've been thinking about:
Foo_Base
Foo_Abstract
Abstract_Foo
Base_Foo
The use of underscores and letter case is irrelevant.
Edit: It seems like the Zend Framework uses a "Abstract" suffix (source).
Do you think it's a good practice to differentiate abstract from non-abstract classes by giving their name a prefix or a suffix?
Unless you're following some convention, I would suggest not to attach this type of meta-data to your class names. Basically it clutters the code with information available elsewhere. To me it resembles hungarian notation which is loathed by many programmers.
Here are a few "formats" I've been thinking about...
If I had to choose, I'd go with AbstractFoo.
According to these PHP Coding Standard you should really avoid _:
Class Names
Use upper case letters as word separators, lower case for the rest of a word
First character in a name is upper case
No underbars ('_')
Justification
Of all the different naming strategies many people found this one the best compromise.
Example
class NameOneTwo
class Name
Probably not with a direct reference to a (1) derived class...
In a real situation there usually is a domain-specific collective name available.
But when there isn't I usually go with something like BaseViewModel
Foo_Abstract or Abstract_Foo is a bad idea if you plan to use namespaces, as you will have Foo\Abstract, which is invalid.
I think it is bad practice to name variables/functions/classes based on the type that it represents. int myInt is good for coding a quick example (perhaps in a classroom setting) but thats about it.
abstract class AbstractClass is too redundant and annoying to read. Let your programs/code say a lot in a concise way, and speak for themselves. From reading the definition I know its an abstract class I shouldn't need to be reminded in the name of the class. Focus on what purpose the class has in reference to the problem instead of what type of class it is.
This is the gist of things I got from Clean Code
If you describe the project I can suggest good names that aren't redundant.
Why don't you actually want to specify a class to be abstract then you should use the abstract keyword in PHP
abstract class MyClass
{
//**
}
If you want a way to check for abstract classes such as logical checks then you should create an interface like so:
interface IAbstract
{
}
and then declare the class with it
abstract class MyClass implements IAbstract
{
//**
}
and then you can check like so:
if(MyClass instanceof IAbstract)
{
//Abstract
}
This way you don't need to change your class names to suit the object types.