NotionCommotion Posted February 19, 2017 Share Posted February 19, 2017 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 Quote Link to comment Share on other sites More sharing options...
dalecosp Posted February 20, 2017 Share Posted February 20, 2017 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. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted February 20, 2017 Author Share Posted February 20, 2017 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! Quote Link to comment Share on other sites More sharing options...
ignace Posted February 21, 2017 Share Posted February 21, 2017 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. 1 Quote Link to comment Share on other sites More sharing options...
kicken Posted February 21, 2017 Share Posted February 21, 2017 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. 1 Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted February 21, 2017 Author Share Posted February 21, 2017 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. Quote Link to comment Share on other sites More sharing options...
kicken Posted February 21, 2017 Share Posted February 21, 2017 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. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted March 5, 2017 Author Share Posted March 5, 2017 (edited) 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 March 5, 2017 by NotionCommotion Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.