|
|||||||
New to SitePoint Forums? Register here for free!
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Mlle. Ledoyen
![]() Join Date: Jan 2001
Location: UK
Posts: 7,312
|
Interfaces
Bear with me, rambling helps me think!
Would I be right in thinking that interfaces allow you to specify the methods that should exist in a class, allowing you to, for example, create an API? My thinking and research suggests you would go about it something like this with PHP4: Interface, which defines the API: PHP Code:
PHP Code:
Sean ![]() |
|
|
|
|
|
#2 | |
|
SitePoint Addict
![]() ![]() ![]() Join Date: May 2002
Location: London
Posts: 302
|
Quote:
![]() |
|
|
|
|
|
|
#3 |
|
Mlle. Ledoyen
![]() Join Date: Jan 2001
Location: UK
Posts: 7,312
|
Yippee!Next question, again using a data access object. If you were splitting the methods of your DAO into a number of classes, so that you are grouping related methods, would you create an interface for each related group or use one large interface which each class of related methods uses? If you get what I mean by that very long sentence ![]() Sean ![]() |
|
|
|
|
|
#4 |
|
Mlle. Ledoyen
![]() Join Date: Jan 2001
Location: UK
Posts: 7,312
|
Perhaps an example would help clarify my question
You're creating an application that will have a number of different parts that need to access stored data, such as session data, user data and monkey data (we all like a bit of monkey data ). Would you create one interface that covers all these things or would you create one interface for session data, one for user data and one for the monkeys?Sean ![]() |
|
|
|
|
|
#5 | |
|
SitePoint Addict
![]() ![]() ![]() Join Date: May 2002
Location: Gent, Belgium
Posts: 283
|
On the interface design in PHP4, I am doubting between 'correctness' and performance...
Since, the interface does not contain any real programming purpose (this is not very well put, but I hope you'll understand what I'm trying to say ), it imposes a 'useless' overhead since every class extending on the interface class must include it, resulting in disk access and parse time overhead...I write interfaces too, just for having a base api reference really, but in my code I don't include them and I write PHP Code:
So I'm still doubting about it really ![]() Quote:
If so, I'd go for one interface, makes it simpler for the code that uses the objects, it doesn't have to check the exact type of objects it uses, it can just call some methods on it, which are always the same. (Which I guess is a little what polymorphism is all about?) Argh man, this OOP/Design patterns thing sometimes has my brain soooo running around in circles... But I like it ![]() |
|
|
|
|
|
|
#6 | |
|
Mlle. Ledoyen
![]() Join Date: Jan 2001
Location: UK
Posts: 7,312
|
Quote:
![]() Sean ![]() |
|
|
|
|
|
|
#7 | ||
|
public static void brain
![]() ![]() ![]() ![]() ![]() Join Date: Jun 2002
Location: Montana, USA
Posts: 650
|
Quote:
Interfaces allow you to set down solid guidelines for your class hierarchy, and they *force* you to conform to those guidelines. Good example (along with the DAO), would be i/o access. No matter what your source and destination are, you should always use the same methods to get there... So say you are coding to the following interface: PHP Code:
Quote:
|
||
|
|
|
|
|
#8 | ||
|
SitePoint Addict
![]() ![]() ![]() Join Date: May 2002
Location: Gent, Belgium
Posts: 283
|
Gybbyl, I can totally understand your points of view...
And I have to say I'm likely too paranoid about performance. Still my desktop is a PIII450/384Mb and my 'production server' is a K6II350/128Mb so I'm nowhere near the 'Gigahertzes and loads of memory', but all in all that's more my problem I reckon ![]() Quote:
Quote:
) and start extending on it, they'd still have the interface classes to base the api on. It's true that the interface is not enforced, but isn't that in fact their problem, I mean *if* I should release such code, I would document it properly and the documentation should make the 'interface-thing' more then clear. Btw, if they write subclasses that do the same thing on related sources, shouldn't then a base class be defined (that /* implements */ the interface) where other classes can inherit from? I just want to make clear that I'm not trying to argue here in a yes no debate, I want to learn, don't we all .My reasoning is a result from reading this thread a while back (starting around post #14). And I also want to state, that It's not my MO to just sacrifice something for a little performance gain. |
||
|
|
|
|
|
#9 |
|
public static void brain
![]() ![]() ![]() ![]() ![]() Join Date: Jun 2002
Location: Montana, USA
Posts: 650
|
Good points all around -- It must be a matter of personal preference, coupled with thought process and peer pressure. Boils down to this: at least we are all using structure in our code.
![]() |
|
|
|
|
|
#10 |
|
SitePoint Victim
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Apr 2003
Location: London
Posts: 2,273
|
Hi...
I am glad someone raised this. I have noticed this argument rear it's head as part of other debates on the forum without it really being tackled head on. Myself I lean on the side of get the library right and well designed, then find out what the bottleneck is. If you then need to improve performance, look at the big things first, e.g. caching, lazy loading or switching to a compiled module. All of these are easier with a clearly designed system, rather than micro-smithing the source code. It can be a very poor return for invested time and the extra code tangling will hurt development time for ever more. If you do all of this and you find that the source code really is the source of your problems then firstly isolate with a class the bits that need optimising. Then branch the code. Leave the unoptimised version as your main development branch and perform the tuning on the other. When you want to do a release you just merge the development branch into your releases branch to get the fast version. A fixed release where nobody ever reads the source is a safe environment for optimisations. I say "just", but of course all of this is extra management. Luckily I have never had to do this for any length of time because the problems that cause performance bottlenecks actually change quite often and the bottleneck disappears of it's own accord. I know that 'Selkirk' holds a more performance oriented view and I would be interested to hear about the experiences that have pushed him or others in that direction. Slightly off topic, but I find that OO is best as a long term investment. This falls into my manager's bad news (which I have shamelessly stolen from others at various times) when changing to OO... 1) Will OO make writing my program easier? No. 2) Will OO make my program run faster? No. 3) Will OO make my program shorter? No. 4) Will OO make my program cheaper? No. The good news is that the answers are yes when you come to rewrite it! ![]() yours, Marcus. |
|
|
|
|
|
#11 | |
|
killall -9 lusers
![]() ![]() ![]() Join Date: Oct 2002
Location: Cincinnati, Ohio, USA
Posts: 395
|
Quote:
![]() |
|
|
|
|
|
|
#12 | |
|
public static void brain
![]() ![]() ![]() ![]() ![]() Join Date: Jun 2002
Location: Montana, USA
Posts: 650
|
Quote:
|
|
|
|
|
|
|
#13 |
|
SitePoint Wizard
![]() ![]() Join Date: Nov 2000
Location: Switzerland
Posts: 2,906
|
Just on the original point, the way I think of interfaces (vs. inheritance) is like this;
Inheritance is a vertical hierarchy Interfaces are horizontal, (possibly) cutting across multiple inheritance hierarchies. A theoretical example might be if I have two inheritance hierarchies like; PHP Code:
PHP Code:
PHP Code:
Using a PHP related example - Vincents Eclipse library, one way it could be modifed to use interfaces for PHP5 could be where the Iterators are concerned. The interface could be; PHP Code:
PHP Code:
PHP Code:
Edit: Note that the actual implementation of the Iterator in MyQueryResult and DataFileReader would be the current QueryIterator and DataFileIterator classes respectively Think Iterators make the about the best example of how interfaces can be used as Iterators are about unify many different types of "collection". More about Iterators here. As to whether methods should be placed in a parent subclass or in an interface, a very rough rule of thumb might be if you require all subclasses to provide a method and in the parent the definition of that method has an empty body (ie doesn't do anything) then consider an interface. Last edited by HarryF; Jul 21, 2003 at 05:43. |
|
|
|
|
|
#14 | ||
|
SitePoint Addict
![]() ![]() ![]() Join Date: May 2002
Location: Gent, Belgium
Posts: 283
|
Quote:
Still, using die(), you could put out a more explaining (explicative? explanatory?) error than 'call to undefined function', what, in the end, was what I was trying to say. I hope I cleared that one up a bit, not only is my brain spinning on the OOD part, also my english seems to be causing me more trouble than I'd like to admit sometimes ![]() lastcraft, reading over your post, I'm realizing I'm putting too much effort and time in performance at the wrong time in the development process, I should optimize later (if ever?)... I think it's also a psychological thing: when I know I've got code that could be made faster, however small the gain (without sacrificing things like layering etc...), I have to optimize it, I can't seem to help it... This is probably just stupid pride on my behalf ![]() HarryF, in the example code you posted, suppose you also have an interface Drive, can a 747 be implemented something like this: PHP Code:
So the 747 can taxi to the runway? About the iterator-discussion, I'm terribly puzzled, isn't decoupling the iterator from the collections it iterates over a more preferable way? Implementing an iterator interface in every class that could need iterating at some point seems very 'dangerous' for possible bloatness. If you need iteration, instantiate an iterator for the specific collection, if not, you don't, less dead code, no? Just questions, my brain ain't spinning enough, and these discussions are way cheaper than the drugs I usually have to take to achieve the same result. lol. |
||
|
|
|
|
|
#15 | |||
|
SitePoint Wizard
![]() ![]() Join Date: Nov 2000
Location: Switzerland
Posts: 2,906
|
Quote:
Quote:
In theory I guess the answer is yes but in practice, when you consider performance (premature - yes I know but PHP is not compiled), how you usually need to build your own numeric index to keep track of the sequence and the question "Has this now become more complicated to use than native PHP functions?" it generally ends up being better to implement the iterator API into the collection. Probably someone can give you a better answer than that but as to bloat, the iterator I usually prefer for most things I'm doing is lightweight (it has weaknesses but in most cases it's all I need); PHP Code:
If you need a more robust iterator, which won't choke on false values in the collection but still relies on PHP's sequencing rather than having to track your own index, the trick is using PHP's reset() function for which you need to read the docs carefully; Quote:
|
|||
|
|
|
|
|
#16 |
|
SitePoint Guru
![]() ![]() ![]() ![]() ![]() Join Date: Nov 2002
Posts: 848
|
Ok, I've been harping alot lately about PHP being a dynamicly typed language. A recap:
Static Typing: Check for type compatability as soon as you can (compile time). Dynamic Typing: Check for type compatability as late as you can (runtime). Staticly typed languages such as C# and Java REQUIRE interface declarations. Dynamically typed languages do not. So I will refer to this style as an informal interface: PHP Code:
PHP Code:
Lets look at how interfaces are used in those Statically typed languages that require that they be declared. Take a look at this article Are delegates the moniker of .NET? (if you have time, use google to track down some of the discussion on this article, its better than the article.) Notice that delegates are like interfaces except that they do not require the callee to declare an explicit interface. The caller must have access to the interface declaration in the form, but it is not necessary for the target to explicitly declare the implementation of an interface. Anonymous classes in Java are used for the same purpose. If interface declarations are so good, why do these staticly typed languages keep using such cumbersome methods of avoiding them? On a different track, I talk in This post about a productivity study I did where team A was twice as productive as team B. What has only recently occurred to me was that the productive team A used a dynamicly typed language and less productive team B used a statically typed language. This study has formed the basis of many of my views of programming and this realization rocks my world. Gyybyl talks about 'forgetting' and 'enforcing' in his post. In my experience, forgetting is not an issue and enforcing is time consuming. To use a recent popular term, 'enforcement' is not agile. Counter intuitively, I believe that early type checking is less productive because it requires more of that useless non-value added code that I talked about in my productivity comparison. Less code is better. (period.) See Strong Typing versus Strong Testing for a more eloquent explaination. Or lets put it another way. You are programming in a language that lets you do stuff like this: PHP Code:
PHP Code:
|
|
|
|
|
|
#17 |
|
SitePoint Victim
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Apr 2003
Location: London
Posts: 2,273
|
Hi.
One very definite timesaver with interfaces is for library writers "enforcing" objects on their victims that their libraries can work with. If I write a class for an object which I think works with this library it may take a little while to find out that it doesn't work, usually an unexepected error saying that a method does not exist that was expected. I look more deeply at the code and find that I have misunderstood things completely. The advantage of an interface check is that I would have found out as soon as I passed the object in. I could also have looked up the interface to see what was expected and so seen that I was on the right track or not. I use this example because I've got a real habit of doing this. Ok, had I read the documentation or code more carefully I should have known anyway, but that little interface block works so much more decisively. Now the rambling part... There is an interesting point here about testing in that you only test single infinitessimal points along a (near) continuium of possibilities. This is similar to scientific non-proof. You cannot prove a theory with experiments anymore than you can prove something works with testing. Declarations, such as "interface", act as genuine laws, however. I think the weakness of declarations (I haven't used Eiffel) is that you are already thinking declaratively when coding, even when translating it into algorithms in your head, and this means that you are writing it twice in a similar way. The testing approach is weaker, but is a such a different viewpoint as to act as a very strong check. yours, Marcus. |
|
|
|
|
|
#18 |
|
SitePoint Guru
![]() ![]() ![]() ![]() ![]() Join Date: Nov 2002
Posts: 848
|
I ran in to this article recently:
Python & Java: a Side-by-Side Comparison It does a good job of comparing dynamic typing versus static typing and its effect on productivity. Many of the points he makes for python are valid points for PHP. |
|
|
|
![]() |
| Bookmarks |
«
Previous Thread
|
Next Thread
»
| Thread Tools | |
| Display Modes | |
|
|
|
All times are GMT -7. The time now is 01:43.







Yippee!
). Would you create one interface that covers all these things or would you create one interface for session data, one for user data and one for the monkeys?






Linear Mode
