Page 1 of 1
Parameter Object vs. Parameter Array vs. Parameter Functions
Posted: Sat Aug 26, 2006 10:52 pm
by Ambush Commander
A well known design smell is when you've got too many parameters in a function. The usual solution is to put the parameters in a parameter object and pass them to the function. You can also defer setting parameters to later function calls.
Well... I'm using the latter case and it doesn't look very pretty to me. Example:
Code: Select all
HTMLPurifier_ConfigDef::define(
'Core', 'Encoding', 'UTF-8',
'Defines the input and output character encodings to use. HTMLPurifier '.
'internally uses UTF-8, making that the painless default choice. Note '.
'certain implementations of HTMLPurifier_Lexer are intelligent enough '.
'automatically detect encoding, however, output format will always be '.
'this value. Currently supported values are UTF-8 and '.
'ISO-8859-1 (ISO8859-1). Encoding names are case sensitive.'
);
HTMLPurifier_ConfigDef::defineAllowedValues(
'Core', 'Encoding', array('UTF-8', 'ISO-8859-1')
);
HTMLPurifier_ConfigDef::defineValueAlias(
'Core', 'Encoding', 'ISO8859-1', 'ISO-8859-1');
Those extra parameters, however, are optional and aren't used all the time. What do you think would be a nicer/prettier way to do this sort of thing?
Re: Parameter Object vs. Parameter Array vs. Parameter Funct
Posted: Sat Aug 26, 2006 11:13 pm
by Christopher
Ambush Commander wrote:A well known design smell is when you've got too many parameters in a function. The usual solution is to put the parameters in a parameter object and pass them to the function. You can also defer setting parameters to later function calls.
The usual solution is to first see if having many parameters is actually a problem. It it actually is a problem there are a number of things you would probably do before resorting to a Parameter Object -- which is more for parameters that you don't have a home for. I would suggest for reducing the parameters to only those actually needed adn/or replacing a parameter with a method as first steps.
Posted: Sun Aug 27, 2006 5:39 am
by Ollie Saunders
4 is not too many parameters.
Posted: Sun Aug 27, 2006 9:24 am
by Ambush Commander
4 is not too many parameters.
As of right now, having too many parameters is not too much trouble. The difficulties arise when I start adding more constraints: besides allowed values and value aliases, there could also be allowed types, case sensitivity, allowed setters, etc etc. But then again, eight still isn't that much...
Posted: Sun Aug 27, 2006 9:34 am
by Chris Corbyn
I believe these parameters arise from configuration directives in your library? In which case using a parameter object seems like a good idea to me.
I've done similar things myself, though where things may have been intended to be ignored or used in different ways (like your array() to group directives) I may have had simple sub-objects whereby "instanceof" could be used to figure out what do do with the values. I was just making it up as I went along however.
So like:
Code: Select all
HTMLPurifier_ConfigDef::defineAllowedValues(
'Core', 'Encoding', new DefGroup('UTF-8', 'ISO-8859-1')
);
Hmm... probably getting even messier. You could make factory functions to make that more readable:
Code: Select all
HTMLPurifier_ConfigDef::defineAllowedValues(
'Core', 'Encoding', DefGroup('UTF-8', 'ISO-8859-1'),
Comment('This is an instance of "new Comment()" so it can just be ignored.')
);
I understand why you are wanting to use such objects though. How will you be retreiving values from the object? Do you have a helper object to do this or have you built methods into the parameter object class anyway?
Posted: Sun Aug 27, 2006 9:39 am
by Ambush Commander
The trouble is that I
must maintain namespacing, meaning all the parameter objects must have HTMLPurifier_ prefixed.
How will you be retreiving values from the object?
When you create a configuration object, it must be passed a definition object. It then references the values in there to determine whether or not config options are okay.
Do you have a helper object to do this or have you built methods into the parameter object class anyway?
Their built into the object.
Posted: Sun Aug 27, 2006 10:14 am
by Ollie Saunders
Ambush Commander wrote:The difficulties arise when I start adding more constraints: besides allowed values and value aliases, there could also be allowed types, case sensitivity, allowed setters, etc etc. But then again, eight still isn't that much...
If you are going to have a lot of constraints it makes sense that you will need a lot of code to declare them all and its not duplication so its not really a problem.
What you are doing here seems really cool to me, a very elegant solution, I don't really understand what you are concerned about.
Posted: Sun Aug 27, 2006 10:54 am
by Chris Corbyn
ole wrote:What you are doing here seems really cool to me, a very elegant solution, I don't really understand what you are concerned about.
I think it's mostly a combination of aesthetics and user-friendliness. With the level of flexibility to you're aiming at through, I agree that this is an elegant solution.
Posted: Sun Aug 27, 2006 11:00 am
by alex.barylski
d11wtq wrote:ole wrote:What you are doing here seems really cool to me, a very elegant solution, I don't really understand what you are concerned about.
I think it's mostly a combination of aesthetics and user-friendliness. With the level of flexibility to you're aiming at through, I agree that this is an elegant solution.
Again...this is an example of when computer science becomes a computer art
What an interesting field we all work in

Posted: Sun Aug 27, 2006 1:53 pm
by Ambush Commander
Well, if anyone's interested in how things turned out, I ended up not changing the external interface.. too much.
Code: Select all
HTMLPurifier_ConfigDef::define(
'Core', 'Encoding', 'utf-8', 'istring',
'Defines the input and output character encodings to use. HTMLPurifier '.
'internally uses UTF-8, making that the painless default choice. Note '.
'certain implementations of HTMLPurifier_Lexer are intelligent enough '.
'automatically detect encoding, however, output format will always be '.
'this value.'
);
HTMLPurifier_ConfigDef::defineAllowedValues(
'Core', 'Encoding', array(
'utf-8',
'iso-8859-1'
)
);
HTMLPurifier_ConfigDef::defineValueAliases(
'Core', 'Encoding', array(
'iso8859-1' => 'iso-8859-1'
)
);
We've got an extra type variable, in this case it's istring, or case-insensitive string.
The internals, however, were totally revamped.
The code is here:
http://hp.jpsband.org/svnroot/htmlpurif ... figDef.php
http://hp.jpsband.org/svnroot/htmlpurif ... Config.php
Still don't have documentation generating code yet, going to work on that next.