How often do you use text configuration files like ini, cfg, rc, xml, properties? Do you write handlers for them that parse strings and interpret commands?
And I propose another way - to write configurations in a scripting language (PHP, JavaScript, etc.), using the convenience of object-oriented programming.
Example 1
Suppose the banner.ini file contains information about banners that need to be displayed on a web page:
[Roga-Kopyta]
type = flash
width = 100
height = 100
src = roga-kopyta.swf
link = www.roga-kopyta.com
[SuperPuper]
type = image
width = 468
height = 60
src = superpuper.jpg
link = www.supper-pupper.net
As a rule, in this case data is required to be read, checked for correctness, parsed and put into an array for further processing. So why not immediately write the same data as a ready-made array?
$banners = array (
// Roga-Kopyta
array ("type" => "flash",
"width" => 100,
"height" => 100,
"src" => "roga-kopyta.swf",
"link" => "http://www.roga-kopyta.com"),
// SuperPuper
array ("type" => "image",
"width" => 468,
"height" => 60,
"src" => "superpuper.jpg",
"link" => "http://www.supper-pupper.net")
);
In clarity, the code is not lost, but now, on the other hand, the input file does not need to be parsed! However, this is not all. If you go further, you can immediately determine the object's behavior in the same file by assigning a handler class to it.
')
$banners[] = new FlashBanner(100, 100, "roga-kopyta.swf",
"http://www.roga-kopyta.com");
$banners[] = new ImageBanner(468, 60, "superpuper.jpg",
"http://www.supper-pupper.net");
In the meantime, the FlashBanner and ImageBanner child classes will describe the difference between these banner types when displaying on the page. Moreover, now instead of ifs and switches for analyzing properties there will be only one call to the virtual method.
abstract class Banner {
protected $width, $height, $src, $link;
public function __construct($width, $height, $src, $link) {
...
}
public function display() {
$html = $this->toHTML();
...
}
abstract public function toHTML();
}
class ImageBanner extends Banner {
public function toHTML() {
return "<a href='{$this->link}'><img src='{$this->src}' " .
"width={$this->width} height={$this->height}'></a>";
}
}
class FlashBanner extends Banner {
public function toHTML() {
return "<object>...</object>";
}
}
After that, all the “processing” of the configuration file will be reduced to a pair of lines:
include "banners.php";
foreach ($banners as $banner) {
$banner->display();
}
Example 2
And in our projects a special role is played by self-interpreted files describing the database configuration. By connecting such a configuration file, we immediately get a class hierarchy for all tables with all fields, and each field, inheriting one of the standard classes IntField, StringField, DateField, etc., will automatically acquire methods for formatting, for checking for correct input, for links to other tables, etc.
class Table_users extends Table {
function __construct {
$this->fields["id"] = new users_id();
$this->fields["login"] = new users_login();
$this->fields["password"] = new users_password();
$this->fields["group"] = new users_group();
$this->fields["registred"] = new users_registred();
}
}
class users_id extends IntField {
public $flags = BasicField::PRIMARY_KEY;
}
class users_login extends StringField {
public $size = 50;
}
class users_password extends StringField {
public $size = 255;
}
class users_group extends IntField {
public $foreignTable = "groups";
public $foreignKey = "id";
}
class users_registred extends DateField {
public $format = "d/m/Y";
}
...
class StringField extends BasicField {
public function validate($value) {
return is_string($value) && strlen($value) <= $this->size;
}
public function toHTML($value) {
return htmlspecialchars($value);
}
}
class DateField extends BasicField {
public function validate($value) {
...
}
public function toHTML($value) {
return date($this->format, $value);
}
}
Example 3
The data in the self-interpreted form need not be manually entered, and, of course, the data processing language can be any, up to the machine code. At the previous work, we used a rather interesting way to optimize the font storage format for the fastest text output to the screen. Each letter of the font was compiled into a set of machine instructions that draw a point or line in the desired position. As a result, the C code for the output line looked like this:
for (char* c = str; *c != 0; c++) {
x += font[*c](x, y);
}
Conclusion
Presentation of data in the form of performing constructions of a programming language allows, without loss of clarity, to significantly simplify the mechanism for processing these data, saving on the verification of correctness and analysis of constructions (which the programming language translator itself performs), as well as on data interpretation and the description connection with behavior.
PS And we are interested in the web programmer’s work here -
habrahabr.ru/job/2277