|
From: <gh...@nc...> - 2001-10-26 00:21:25
|
I'm happy to report that I am now in a position to put together a
working foundation class library fairly quickly. I would be
embarassed to say how long it took me to get this far but suffice it
to say that it has been a very good learning experience. There was
a bit of a learning curve to working with code in packages.
In this post I want to explain what I propose to do and ask for
comments to see if there is a consensus on it and related issues.
Ok, let's start with some sample foundation class library code.
Here is the current Foundation.curl.
------------------------------------------------------------------
||foundation class for curl-email project
{curl 1.6 package}
{package ORG.CURL-EMAIL.FOUNDATION,
author="",
version="0.1"}
{import * from CURL.GUI.BASE}
{import * from CURL.GUI.CONTROL-BASE}
{import * from CURL.GUI.CONTROLS}
{import * from CURL.GUI.EXTRAS}
{import * from CURL.GUI.SINGLETON}
{import * from CURL.GUI.STANDARD}
{import * from CURL.GUI.TEXT-EDIT}
{import * from CURL.GUI.TEXT-FORMATS}
{define-class public MyVBox {inherits VBox}
{constructor public {default ...}
{construct-super ...}
}
}
{define-proc public {my-vbox ...}:MyVBox
{return {MyVBox ...}}
}
{define-class public MyHBox {inherits HBox}
{constructor public {default ...}
{construct-super ...}
}
}
{define-proc public {my-hbox ...}:MyHBox
{return {MyHBox ...}}
}
{define-class public MyCommandButton {inherits
CommandButton}
{constructor public {default ...}
{construct-super ...}
}
}
{define-proc public {my-commandbutton
...}:MyCommandButton
{return {MyCommandButton ...}}
}
{define-class public MyTextField {inherits
TextField}
{constructor public {default ...}
{construct-super ...}
}
}
{define-proc public {my-textfield
...}:MyTextField
{return {MyTextField ...}}
}
------------------------------------
This is largely based on examples from the curl
basic docs for using rest arguments and the curl
gui docs for building custom controls.
Here is code that exercises the package above.
-------------------------------------------
{curl 1.6 applet}
{import * from ORG.CURL-EMAIL.FOUNDATION,
location="file:///c:/cvs/curlmail/curl-
email/Foundation.curl"}
{value
{MyVBox "test", background="pink", font-size=14}
}
{value
{my-vbox "test", background="yellow", font-
size=14}
}
{value
h:MyHBox = {my-hbox
background="blue"}b:MyCommandButton = {my-
commandbutton}
{h.add b}
{h.add {my-commandbutton}}
{h.add {my-textfield width=3in}}
}
-----------------------------------------
(some of the code lines probably got wrapped in
odd places but hopefully the intent is clear)
I suppose it is obvious that these rasise a
swarm of questions/issues.
I have worked with vendor supplied class
libraries prior to curl and one of the golden
rules that I have accepted is that you never
create an object in code that inherits directly
from a vendor library object. Instead all
objects inherit from your own objects in your
own libraries. Hence the idea of a foundation
class library that holds all your lowest level
objects that inherit directly from vendor
library objects. The result is that you can
make global changes in any of your objects by
changing the corresponding ancestor object in
your foundation class.
So with the sample code above, instead of having
VBox objects throughout your code you would have
MyVBox objects. I've seen the advantages of
doing this on some fairly large projects and it
is hard to contemplate the alternative.
Ultimately you would probably have several other
objects in a UI package that inherit from MyVBox.
You have probably read Dan Breslau's post where
he suggests that the golden rule cited above may
not be warranted and for sure suggests that
objects should be named according to their
function. My intent here is to get a feel how
the rest of the team thinks on these issues and
not to suggest that mine is the only way to go.
I am new to programming in curl and suspect most
of the team are relatively new to it too. My
experience with this type of situation is that
about the time we get the project finished is
when we'll know how we wish we had done it from
the beginning. Having a foundation class object
underneath all our objects will give us the
chance to go in and do some of the things we
wished we had done in the beginning with the
least amount of effort.
The base class objects are the most generic
objects of a given type that we will have. In
the spirit of giving them descriptive names we
could use GenericVBox instead of MyVBox or maybe
GenVBox. I am personally not fussy about the
exact name buy do prefer something rather short
and consistent. Note in the package code above
I have written a function for each class that
returns an object of the given class. This
would add a layer of indirection that may prove
valuable and I like it because the curl naming
conventions mean that function names are all
lower case. So whether to create all objects
through a function, directly from the class
name, or a mix of the two is a related question.
Finally a few smaller questions to think about.
The location specifier in the package
declaration above is specific to my computer so
we need to find a way to deal with that.
And how about author and version in the package
declaration. Are we going to use our own names
or a team name and what version to use for now?
And what about the file name Foundation.curl?
Do we want to think about standards for file
names and indentifier names? Also points of
style such as spaces around assignment
operators, etc.
I'm ready to move quickly on building a
foundation class which for starters would hold
all the visual GUI classes that I can come up
with. Foundation classes can also be valuable
for non-visual objects but it depends a lot on
what you're doing with them.
Your comments are requested and appreciated.
Gene H.
|