Page 1 of 1

Conceptual design for OOP toolkit..

Posted: Mon Apr 05, 2004 12:16 pm
by Roja
I'm currently in the design phase of a PHP toolkit.

Explaining might help a bit in answering my question, so forgive a bit of text..

JOMPT (Just one more php toolkit) will essentially be a framework. You install JOMPT, and then you install items into it (under its root).

Items can be things like phpbb, online web-based games (The Kabal Invasion, Legend of the Green Dragon, WORDOG), and even web-based chat scripts.

JOMPT would provide a variety of functionality, but each is dependent on what items you've installed in JOMPT.

For example, you can install Smarty into Jompt, and then all items under JOMPT would have smarty functionality available. Similarly, if you have installed PHPBB under JOMPT, all games, chat scripts, etc, can utilize the same login for all of them.

My question is what form should the interface I provide be?

I could simply configure and provide the raw interfaces from the original backend utilities ($smarty->display('file.tpl')), or I could extend their classes to form a unique class ($jompt->display('file.tpl')).

Which is more appropriate from an OOP point of view, and from a developers point of view, which is going to be more attractive?

If there are alternative designs for the interface you can envision that I didnt think of, feel free to bring them up.

I've done some extensive OOP coding in the past, but I'm looking to start from the beginning with some solid OOP designs, so everyone's feedback is very welcome.

Posted: Mon Apr 05, 2004 3:03 pm
by Weirdan
I'd recommend you to go with aggregation rather than with delegation.
Such type of 'proxy delegation' would make the interface of your class cluttered with a lot of things that simply do not work (if I haven't installed the smarty there is still 'display' method exists). You can find the COM way useful in your case:

Code: Select all

$jompt = new jompt;
 if( $smarty = $jompt->QueryComponent('smarty') ) {
    $smarty->display('file.tpl');
 } else {
    die('This application requires the SMARTY component to be installed and properly registered in JOMPT');
 }

Posted: Tue Apr 06, 2004 10:23 am
by Roja
Weirdan wrote:I'd recommend you to go with aggregation rather than with delegation.
Such type of 'proxy delegation' would make the interface of your class cluttered with a lot of things that simply do not work (if I haven't installed the smarty there is still 'display' method exists). You can find the COM way useful in your case:

Code: Select all

$jompt = new jompt;
 if( $smarty = $jompt->QueryComponent('smarty') ) {
    $smarty->display('file.tpl');
 } else {
    die('This application requires the SMARTY component to be installed and properly registered in JOMPT');
 }
I'm unfamiliar with COM. I read through the php manual pages on it, and several informative webpages, but they seem to imply its a windows-specific thing. Is that inaccurate?

The example you gave is great, and definitely preferable, but I don't quite understand the QueryComponent call.. mind explaining in a bit more detail?

Posted: Tue Apr 06, 2004 1:49 pm
by Weirdan
Roja wrote:
Weirdan wrote:

Code: Select all

$jompt = new jompt;
 if( $smarty = $jompt->QueryComponent('smarty') ) {
    $smarty->display('file.tpl');
 } else {
    die('This application requires the SMARTY component to be installed and properly registered in JOMPT');
 }
I'm unfamiliar with COM. I read through the php manual pages on it, and several informative webpages, but they seem to imply its a windows-specific thing. Is that inaccurate?
We are talking about the desing, aren't we? =) Indeed, implementation is platform-specific (AFAIK there are opensource implementations exists though), but design isn't tied up to some platform.

Idea behind this snippet is that jompt class implements QueryComponent (named after QueryInterface in COM) method as follows:

Code: Select all

if required component registered 
     return it's instance
else 
     return false
'required component registered' part is up to you to implement. Perhaps it would check the config files, include required class files, instantiate the class(es) and finaly return the object which represents the component.
Roja wrote: The example you gave is great, and definitely preferable, but I don't quite understand the QueryComponent call.. mind explaining in a bit more detail?
If you go this way you need to keep in mind certain things:
  • all components, even the most complex ones, should be represented by their classes (one per component). It's not that easy to put, say, phpbb functionality in one class =)
  • name of the component should be unique, so if someone calls his package 'Smarty' - I can't use this name for my own. To solve this particular problem GUIDs are used in COM (GUID stands for Globally Unique IDentifier).
Perhaps there exist even more limitations which I don't see at the moment...

Posted: Tue Apr 06, 2004 1:58 pm
by McGruff
As a purely personal view, I'm less interested in a framework than in a toolkit which could be used in any project.

Still, a framework that easily integrates a variety of common php apps would be a neat trick to pull off and might be very useful to many.

Watch out for licensing issues if different apps have different open source licences.

Wierdan's idea about the interface looks good.

Code: Select all

$smarty->display('file.tpl')
..says more to me about what is going on than:

Code: Select all

$jompt->display('file.tpl')
And, since your app will integrate many components, there might even be a choice of template engines (?) - with the former it's immediately obvious which one is being used.

Posted: Tue Apr 06, 2004 1:58 pm
by Weirdan
Regarding the 'one class per component' issue: You may find the Facade pattern useful in this case

Posted: Tue Apr 06, 2004 9:54 pm
by Roja
McGruff wrote:As a purely personal view, I'm less interested in a framework than in a toolkit which could be used in any project.
Well, the idea is that JOMPT itself is minimalist. It provides a common install/setup and administration method. Then you add what you want, whether thats Smarty or some other template engine, games, forums, and so on.

It expands with your needs, and provides a single interface for a variety of tools.

In some ways, it fits both the "toolkit", and the "framework" models.

Obviously, at its core, its going to have extremely re-usable items (toolkit) but its power will really shine at the framework level.
McGruff wrote: Still, a framework that easily integrates a variety of common php apps would be a neat trick to pull off and might be very useful to many.
Yeah, its a worthwhile goal. :)
McGruff wrote: Watch out for licensing issues if different apps have different open source licences.
I'm extremely aware of licensing issues, and will be doing my best to clarify them and make it easy for admins to stay within the law.
McGruff wrote: Wierdan's idea about the interface looks good.

Code: Select all

$smarty->display('file.tpl')
..says more to me about what is going on than:

Code: Select all

$jompt->display('file.tpl')
Agreed.
McGruff wrote: And, since your app will integrate many components, there might even be a choice of template engines (?) - with the former it's immediately obvious which one is being used.
Yes - exactly. While I somewhat liked the idea of an abstraction, the truth is that that would require *much* more work than doing a collection.

Posted: Wed Apr 07, 2004 6:51 am
by patrikG
Roja wrote:
McGruff wrote: And, since your app will integrate many components, there might even be a choice of template engines (?) - with the former it's immediately obvious which one is being used.
Yes - exactly. While I somewhat liked the idea of an abstraction, the truth is that that would require *much* more work than doing a collection.
True, but if you think about modality - you would simply add a driver for the a template engine / db-wrapper / etc. - abstraction is, to my mind, really the only way to go (the driver-implementation of adoDB comes to mind). Collections tend to become quite cumbersome, especially if you're having many, many, many heterogenous sources (which you will).

Posted: Wed Apr 07, 2004 10:33 am
by Roja
patrikG wrote: True, but if you think about modality - you would simply add a driver for the a template engine / db-wrapper / etc. - abstraction is, to my mind, really the only way to go (the driver-implementation of adoDB comes to mind).
I do deeply respect the work/design of adodb. It weighs on my mind in this decision.

However, the point made earlier is still true - if we abstract a general class ("template"), then we not only get the lowest-common-denominator, we also have to engineer module-specific code for each.

In other words, in a collection-style, you add smarty, and now the smarty->blah() methods become available with some code to handle the "is it there, register it, etc" condition.

In an abstraction, you'd need that code, AND code to convert non-similar method names, variable names, and so on to make them more consistent. Then you'd also need code to ensure that each acts similarly and consistently - some functions from Smarty no doubt work differently from FastTemplate.

Collection-style leaves most of the work on the original module authors (smarty, adodb), abstraction puts considerably more work on JOMPT.

All of that said, yes, I agree, there is a beauty to the design and implementation of adodb, but I fail to be persuaded that the benefits outweigh the additional code/work.

I'd be very interested in more discussion of it though.. thats pretty much why I asked it here. I haven't decided anything yet.. just leaning in certain directions.

Very open mind. :)

Posted: Wed Apr 07, 2004 3:30 pm
by patrikG
Roja wrote:However, the point made earlier is still true - if we abstract a general class ("template"), then we not only get the lowest-common-denominator, we also have to engineer module-specific code for each.

In other words, in a collection-style, you add smarty, and now the smarty->blah() methods become available with some code to handle the "is it there, register it, etc" condition.
That really entirely depends on what kind of framework you want to write. Having thought about it a bit more, I’ll have to correct my above post: a many-to-many relationship with heterogeneous sources is better implemented with a collection.
What I envisage there is: every user has a favourite in terms of template/database wrapper/form class etc. Through using the collection you’ll be adding complexity, but “user-defined”, and thus scalable, complexity. People can take their pick from a variety of “same” functionality classes. That, I think, really serves the purpose of having a framework for an open source environment much better than abstraction which is basically centralistic.
Roja wrote:All of that said, yes, I agree, there is a beauty to the design and implementation of adodb, but I fail to be persuaded that the benefits outweigh the additional code/work.
I fully agree.

The project really sounds really fascinating – if I had more spare time…(alas, the usual song).

sounds easy, but ain't

Posted: Wed Apr 07, 2004 3:45 pm
by djot
-

Hi,

I observe this topic from the beginning.

Main reason for observing it: I am sure that it is a lot of work to get whatever scripts handled like the goal of Roja is.

I even get my own classes packed together like the aimed goal of Roja is, so I am very excited on learning how to use (e.g.) totally independent template engines, forums of whatever group/coder and so on. (My opinion: All have different features, so it would be impossible to e.g turn off Smarty and turn on some other template engine!)

Also, I am on serach on how to implement modules as easy as for the coder of the framework, modules (extern) developers and modules (noobs) users.


djot
-

Re: sounds easy, but ain't

Posted: Wed Apr 07, 2004 10:33 pm
by Roja
djot wrote:-
I am sure that it is a lot of work to get whatever scripts handled like the goal of Roja is.
Thankfully, I get to cheat a bit.. I have an existing web-based game that has a good amount of code that does "similar" things to a number of my goals.

So, I get to rework that code into the new project, saving some time.

It currently leveredges Smarty, Adodb, md5 routines, some caching, and phpmailer.

Wrapping it up nicely, specifying a clean API for it, and documenting it well will definitely take a few months, but we've begun the process.

So, I don't think it will be too far off.

Posted: Mon Apr 12, 2004 8:13 pm
by lastcraft
Hi.

Regarding avoiding the lowest common denominator. One place where this problem occours a lot is in 3-D graphics cards. The main program would like to draw a square say. If drawSquare() is available it is called, otherwise it uses a software routine that makes other calls. These then go through the same process. The graphic application writers can assume that all of the tools are available even though some are being emulated.

Code: Select all

class SoftwareHandler {
    function drawSquare(...) {
        drawLine(...);
        ...
    }
}
class DumbHandler extends SoftwareHandler {
    function drawLine(...) { ... }
}
class SmartHandler extends SoftwareHandler {
    function drawLine(...) { ... }
    function drawSquare(...) { ... }
}
Combined with the dependency inversion technique (Bridge pattern) it should all be possible, but you are still going to be writing a lot of wrappers :(.

yours, Marcus