Jump to content

Recommended Posts

Still struggling a bit with interfaces.

 

When I just started messing around with them, I started making an interface for all my end classes.

 

But, then started thinking I am going about it wrong, and should start the interface much earlier and not duplicate the capabilities.  For instance, all things exist but this hardly deserves an interface, all vehicles start, stop, turn, etc, so I should make an interface for vehicles, only a motorcycle can pop a wheelie so I should extend the interface, and dirtbikes don't do much more than normal motorcycles (other than being more fun!) so probably should extend it.

 

Now I am thinking that I might not want an interface for a motorcycle, but I want an interface for something that can pop a wheelie.  But isn't that a motorcycle?

 

How should interfaces really be used for these classes?

 

Also, does anyone know of any good tutorials or articles on interfaces?

 

Thanks

Thing->Vehicle->VehicleThatCarriesHumans->Motorcycle->DirtBike
Thing->Vehicle->VehicleThatCarriesHumans->Automobile
Thing->Vehicle->Drone->Phantom

You've Googled?

 

http://www.killerphp.com/articles/php-interfaces/

http://kristopherwilson.com/2015/03/26/using-interfaces-effectively-in-php/

http://www.davegardner.me.uk/blog/2010/11/21/why-you-should-always-use-php-interfaces/  (Older, fanatic OOPer)

http://jaskokoyn.com/2013/06/11/interfaces/

https://www.phpclasses.org/blog/post/300-Using-PHP-Object-Interfaces.html

 

How should interfaces really be used for these classes?

If there's a class that you want to *ensure* has specific capabilities (that is, you don't want to forget to implement the $foo method for it), have it implement an interface.

Thanks dalesosp,

 

I actually mean to change the title of this post from "Any good articles on interfaces?" to a real question, but hit the submit button and then couldn't change it.  The title should have been something like "Should interfaces be applied to end class or extended classes".

 

I have googled and likely have seen some if not all of these.  My difficulty is I am not qualified to know which ones to believe.  Do you recommend any of them, and if so, which ones?

 

Thanks again!

 

You can create an interface for every class in the hierarchy, but that's not really useful.

 

An interface is a type hint essentially. So when you create specialised interfaces there must be a type hint for it in your code to be useful.

  • Like 1

I've never been a big fan of contrived examples like animals, shapes, etc for teaching things like this. They can help provide a rough idea of the purpose of an interface but they don't always help with teaching how to actually use them in real code. I'd suggest instead combining some of these types of tutorials with digging around in actual real-world code that uses interfaces (or whatever) so you can learn not only the purpose of an interface but also when people might choose to use an interface.

 

Should interfaces be applied to end class or extended classes

Whether the class is final or will be extended isn't really relevant to whether or not you want to apply an interface to it. You decide if the interface should be applied by deciding whether you want that class to provide the behavior/api the interface defines.

 

 

How should interfaces really be used for these classes?

Interfaces don't really describe what something is, they describe what something can do. So in your example you'd define your Wheelie interface and apply it to whatever is capable of that action.

 

Interfaces also don't need to describe a specific action, the can describe a collection of actions that are related (eg, a service). For example maybe you have ImageManipulator interface that provides methods like resize, crop, greyscale, blur etc.

 

If you're writing code and trying to determine if you should make an interface or not, think about whether it might be possible to have multiple implementations of some action. If yes, you might consider an interface. If no, probably not worth it.

 

When designing the interface, think about how you want code to use your classes and then define that as an interface. For example just write out the end-user code until you're happy with how that looks, then write your interface to match that, then write the actual implementation to match the interface.

 

For example, say you need some system to manage tokens for use with things like CSRF, password resets, etc. Write code that might use that system until you're happy with how it works.

$tm = $container['token_manager'];

$length = 16;
$expires = (new DateTime())->add(new DateInterval('P1D'));
$token = $tm->createToken($length, $expires, $userId);
$validateUrl = 'https://example.com/reset?'.http_build_query(['id' => $token->getId(), 'token' => $token->getToken()]);
//send reset token
$tm = $container['token_manager'];
$um = $container['user_manager'];

$token = $tm->find($_GET['id']);
if ($token->verify($_GET['token'])){
    $user = $um->find($token->getContext());
    $user->changePassword($_POST['newPassword']);
}
Seems like a reasonable public API so now create the interfaces needed for it.

interface TokenManager {
    public function createToken($length, $expires, $context) : Token;
    public function find($tokenId) : ?Token;
}

interface Token {
    public function getId() : int;
    public function getContext();
    public function getToken() : string;
    public function verify() : bool;
}
Finally create classes that implement those interfaces to provide your token service.
  • Like 1

I've never been a big fan of contrived examples like animals, shapes, etc....

Yeah, I know I am often guilty of this and probably alone, but it actually helps me.

 

 

Whether the class is final or will be extended isn't really relevant to whether or not you want to apply an interface to it.....

But what is the real benefit of some interface of some niche final class which is and will only be that class?  Wouldn't one want to define the interface early so others may extend it as they feel fit.  Oh, I think I understand.  It is not about extending but setting the spec what one might want to implement in the future...

 

 

Interfaces don't really describe what something is, they describe what something can do.....  For example maybe you have ImageManipulator interface that provides methods....

Isn't "ImageManipulator" a noun?  That was my point about what can perform a wheelie.  It must be a motorcycle, but then I am defining a noun.

 

 

If you're writing code and trying to determine if you should make an interface or not, think about whether it might be possible to have multiple implementations of some action...

 

When designing the interface, think about how you want code to use your classes and then define that as an interface....

 

Finally create classes that implement those interfaces to provide your token service.

Makes sense.

But what is the real benefit of some interface of some niche final class which is and will only be that class?

That niche final class is just one particular implementation of the given interface.

class GDImageManipulator implements ImageManipulator {
}
Maybe later you'll create a new separate implementation that does things differently but still accomplishes the same fundamental task.

class ImageMagickImageManipulator implements ImageManipulator {
}

Isn't "ImageManipulator" a noun? That was my point about what can perform a wheelie. It must be a motorcycle, but then I am defining a noun.

In the ImageManipulator case the interface represents an object that can perform a variety of image related tasks. Essentially an image manipulator service. You give it an image and it'll do various things to it.

$manipulator = new GDImageManipulator();
$manipulator->rotate($someImage, 90);
If you wanted to instead create a style where you have an image class which has functions to manipulate it you could use something that conveys that meaning a bit better, maybe ManipulableImage.

 

 

class Image implements ManipulableImage {
}

$image = new Image('somefile.jpg');
$image->rotate(90);
It comes down to what style of API you want to build, which is why I suggested starting with that step. Just write up some pseudo-code for how you think you'd want everything to work then use that the develop your interfaces and final implementations.
  • 2 weeks later...
You indicated earlier that I might first have one class which implements some fundamental tasks:
class GDImageManipulator extends Manipulator implements ImageManipulator {
}

But might later wish to create a new separate implementation that does things differently but still accomplishes the same fundamental task

class ImageMagickImageManipulator extends Manipulator implements ImageManipulator {
}
Note that unlike the example you showed, I am extending both from Manipulator.
EDIT.  just made class Manipulator abstract.  Does doing so change the decision where to apply interfaces?
 
Where should I apply the interfaces?  For instance...
abstract class Manipulator implements Manipulator {
}
interface Manipulator {
}
interface ImageManipulator {
}

or...

abstract class Manipulator {
}
interface ImageManipulator extends Manipulator {
}
interface Manipulator {
}
or something else?
 
Thanks!
Edited by NotionCommotion
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.