08.
Abstracting a Class into 2 Smaller Pieces
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
Whoops, an error! Please, try again later.
9 Comments
All challenges from this course are gone (
What happened?
Hey Ivan!
They're back now! Sorry about that! We had a big internal deploy last night, and well, someone (me) messed up one detail :). But, all should be better now!
Thanks for saying something!
In the answer of challenge 8.1 in StringTransformer.php on line 14
if ($result = $this->cache->fetchFromCache($str)) {should beif ($result === $this->cache->fetchFromCache($str)) {I believe.Hey Dirk,
Well, you're wrong :) It cannot be
if ($result === $this->cache->fetchFromCache($str))because $result var is not defined. Actually, we define it in that if for the first time. You can think of the code:as this:
but the first is shorter and used more often by devs.
Cheers!
whoopsie, you are right, Cheers!
Hey Dirk,
No problem! ;) I know, some of our challenges might be tricky, at least at the first sight. Thank you for reporting a problem anyway, sometimes it might be valid, so better to double check
Cheers!
Hey, I came up with a slightly different result in the first challenge and was wondering if there is anything wrong with the way I did it. The main reason I'm following this coarse is to brush up on things and learn how to structure my code in a way that will mesh with other developers down the road..
Here's a link to the code: http://paste.ofcode.org/Dkn...
As you can see I avoided the code duplication too, but instead of using a private method, I used a private property. Seems that this would be more performant in this particular caching example at the expense of code readability and separation.
The questions I'm left with are:
Am I missing something or or wrong for that approach?
After reviewing both, which would you choose to use in production and why?
Also, I have a habit of changing the parameter names to match the variable names passed in, I think I see why that's bad now, as it seems obvious that the parameter names of the method should match their use in the method.. Am I missing anything not so obvious here?
Thanks for the great track!
Hey PlayIt!
Ah, love the question and seeing your approach :). So in general, of course, if you're avoiding the code duplication - through whatever means - that's best. But, there are a few subtle downsides to using the property versus the private method, at least in this case:
1) Where/When is the $cacheFile property set? Right now, you're setting it in fetchFromCache(). So technically, if someone uses the Cache class in the future and calls saveToCache() first, we'll have a problem.
2) When you have these "service" or "worker" classes, they're meant to be built in a way that makes them reusable over and over again. I mean, like you should be able to use the Cache object to fetch/store many different strings. But when you set the $cacheFile as a property, this is actually the $cacheFile for *one* specific string (since it contains the md5). That's a problem :). Your Cache class should only contain properties (sometimes called "state" or configuration) that describe the behavior of the class *itself*: its properties/state shouldn't start containing configuration for specific instances of it being used, else it gets weird if you re-use it. So, a cacheFile, which is specific to a single cache key is wrong. But, you *could* decide to have a $cacheDir property, which is the *directory* that *all* cache files will be saved in. It's a little unnecessary here, but you could create a __construct() method and set that property inside of there. That property is configuration for the Cache object itself ("where do I store cache files"). If you made your cache class even smarter and started making cached items "expire"after some amount of time, then another good example might be a `$defaultExpirationLength` property, which would be how long each cache file should exist (by default, because perhaps you allow the user to override this via a 3rd parameter to saveToCache) before we consider it expired. That's another good property of how the Cache object works in general. Btw, this topic relates heavily to the topic on "Service classes" (a big topic in part 2 http://knpuniversity.com/sc.... Cache is a service class, so if it has *any* properties, they should only be configuration for how that class works. But, Ship (from the screencast), for example, is a *model* class, whose job is to store data. For those types of classes, the properties represent the data for that *one* object. That's important because, when done nicely, properties have somewhat different jobs in the two types of classes.
So the tl;dr would be: only use a property (instead of a method) if the item in question is really configuration or data for the object as a whole. Phew!
And about your parameter/argument names, yea, I think your instinct is correct :). When you're coding inside, for example, the Cache class, try to imagine that the Cache class is your entire world and nothing else exists. Then ask, "how should I name this parameter?". Of course, the answer will be to name it in a way that describes how it's used inside *that* class. Other devs - or future you! - will thank you in the future: the variable names become a bit of "free" documentation about what those arguments mean.
Thanks for the great question! Cheers!
Future me will thank you for saving me from future headaches.
.. Thanks!
See, I knew it would happen.
"Houston: no signs of life"
Start the conversation!