|
-
Jun 13th, 2010, 11:03 AM
#1
Thread Starter
Hyperactive Member
Factory-esque Design Pattern
I'm wondering how I could implement a design pattern that follows a few guidelines. Not difficult, but I'm having trouble visualizing it, perhaps fatigue is corroding my brain.
A singleton type class that cannot be instantiated that produces objects. The objects produced can only be created through the use of appropriate methods in the main factory class, and cannot be instantiated individually.
Eg:
PHP Code:
Factory::setParams($args); //success
$widget1 = Factory::makeWidget($args); //success
$widget2 = Factory::makeWidget($args); //success
$widget3 = new Widget($args); //fail
$factory = new Factory($args); //fail
I want to do this so I can set parameters in the static Factory class that can then be adhered to by all objects created by it.
Is there a more appropriate design pattern? Any advice? Thank you much in advance
-
Jun 13th, 2010, 12:08 PM
#2
Thread Starter
Hyperactive Member
Re: Factory-esque Design Pattern
(Don't mean to bump my thread, but this is more info than an edit warrants.)
After playing around, I've come up with this. Can anyone see any holes in the logic?
PHP Code:
class Factory{ protected $args; protected static $params; private function __construct(){} public static function setParams($params){ self::$params = $params; } public static function makeWidget($args){ return new Widget($args); } } class Widget extends Factory{ protected function __construct($args){ $this->args = $args; } public function returnParamsAndArgs(){ return parent::$params . "<br />" . $this->args; } } //$factory = new Factory; //should fail //$widget = new Widget("bad"); //should also fail Factory::setParams("foo"); $widget = Factory::makeWidget("bar"); echo $widget->returnParamsAndArgs(); //returns: //foo //bar
It works, but I'm just concerned about larger application of it.
-
Jun 13th, 2010, 01:32 PM
#3
Re: Factory-esque Design Pattern
the only problem I see with that that you might not like is the ability to create widgets using the Widget class:
PHP Code:
echo Widget::makeWidget('test')->returnParamsAndArgs();
so, you can override the method in the Widget class:
PHP Code:
public static function makeWidget($args){ throw new Exception("Cannot use Widget class to create widgets."); }
if you have multiple types of widgets, though, it would be better if the Widget class was an abstract class.
-
Jun 13th, 2010, 01:40 PM
#4
Thread Starter
Hyperactive Member
Re: Factory-esque Design Pattern
Yes, there are multiple types of widgets, so each should be abstract, extending the factory for common properties/methods?
PHP Code:
class Factory{ protected $properties; private function __construct(){} public static function makeWidget($args){ return new Widget($args); } public static function makeWodget($args){ return new Wodget($args); } public static function makeWudget($args){ return new Wudget($args); } }
abstract class Widget extends Factory{ protected function __construct($args){ ... } }
abstract class Wodget extends Factory{ protected function __construct($args){ ... } }
abstract class Wudget extends Factory{ protected function __construct($args){ ... } }
Edit: Wait, that won't work, the makeWidget(), etc., will fail from Widget class abstraction.
----
As well, I suppose it's worth asking, what's the most effective method to pass arguments from the Factory's makeWidget method to the Widget constructor? Instead of doing:
PHP Code:
public static function makeWidget($arg1, $arg2, $arg3, ..., $argN){ return new Widget($arg1, $arg2, $arg3, ..., $argN); }
Is it possible using something like func_get_args() or otherwise to do something like this:
PHP Code:
public static function makeWidget($arg1, $arg2, $arg3, ..., $argN){ $argList = someFunction(func_get_args()); //what could I do here... return new Widget($argList); }
Don't really wanna resort to an eval()'d reconstructed argument string.
Last edited by tomcatexodus; Jun 13th, 2010 at 02:07 PM.
IWS
-
Jun 13th, 2010, 01:56 PM
#5
Re: Factory-esque Design Pattern
no, I meant more like this:
PHP Code:
abstract class abstractWidget extends Factory { protected function __construct($args){ $this->args = $args; } public function returnParamsAndArgs(){ return parent::$params . "<br />" . $this->args; } public static function makeWidget($args){ throw new Exception("Cannot use Widget class to create widgets."); } }
then, every Widget-esque class extends from abstractWidget:
PHP Code:
class Widget extends abstractWidget {
}
class Wodget extends abstractWidget {
}
class Wudget extends abstractWidget {
}
alternatively, you could use debug_backtrace() to figure out what class (if any) is trying to create the object, and fail if it isn't the object you expected. Widget would ideally be abstract in this case, too, and all widgets would extend the base Widget class so that they have the same constructor. instead of changing the constructor, have an initialization method. example:
PHP Code:
<?php
class Factory{ protected static $params; private function __construct(){} public static function setParams($params){ self::$params = $params; } public static function getParams(){ return self::$params; } public static function makeWidget($args){ return new Widget($args); } } abstract class abstractWidget { protected $args; final public function __construct(){ $debug = debug_backtrace(); if(!isset($debug[1]['class']) || $debug[1]['class'] != "Factory"){ throw new Exception("Widgets must be created using the Factory class."); }
// pass all parameters pass to the constructor to the initialization function call_user_func_array(array($this, 'init'), func_get_args()); } final public function returnParamsAndArgs(){ return Factory::getParams() . "\n" . $this->args . "\n"; } // initialization function must be implemented abstract protected function init(); } class Widget extends abstractWidget { // no need for a constructor, just the initialization function: protected function init(){ $args = func_get_arg(0); // this could be annoying, though $this->args = $args; } } header("Content-Type: text/plain"); try { Factory::setParams("foo"); echo Factory::makeWidget("bar")->returnParamsAndArgs(); new Widget('testing'); }catch(Exception $e){ echo $e->getMessage(); } ?>
-
Jun 13th, 2010, 02:04 PM
#6
Re: Factory-esque Design Pattern
oh, and because of the way you're creating stuff with methods, I would suggest passing the class name as a parameter so that your abstract class doesn't need to override so many methods. you can have a create() method that takes a Widget's name and as many arguments as you'd like (using func_get_args()):
PHP Code:
public static function create($class){ if(class_exists($class)){ $arguments = func_get_args(); $obj = new $class($arguments); return $obj instanceof abstractWidget ? $obj : false; // only return if it actually is a widget }else{ throw new Exception("Widget class does not exist"); } }
then you could use it like:
PHP Code:
Factory::create('Widget', 'foo')->someMethod();
you would need to restructure some stuff though.
I hope this is making sense. let me know if it doesn't! I'm just rambling off ideas at this point.
edit: oops, and I forgot that you'd need to remove the first index from func_get_args() when you pass it into the new object, otherwise the widget class name will also be passed.
Last edited by kows; Jun 13th, 2010 at 02:08 PM.
-
Jun 13th, 2010, 02:30 PM
#7
Thread Starter
Hyperactive Member
Re: Factory-esque Design Pattern
Yea, I figured you meant to abstract a widget class and extend it to all the rest.
I'll just override the makeWidget method in the Widget for now.
There's only going to be... 3 (possibly 4?) "widget" classes, so passing classnames as args probably isn't going to be necessary, but considered for further dev.
What about passing args around in the latter part of my last post? Edit: Saw some insight to that in your last post. Any other suggestions?
Last edited by tomcatexodus; Jun 13th, 2010 at 02:35 PM.
IWS
-
Jun 13th, 2010, 02:41 PM
#8
Re: Factory-esque Design Pattern
as far as I know, you wouldn't be able to create the object and pass those arguments to the constructor (without using something like eval() to simulate it). this is where I would have an initialization function within each widget class that would act as a proxy constructor. then, your creation method might do something like this:
PHP Code:
public static function makeWidget(){ $obj = new Widget; if(method_exists($obj, 'init')){ call_user_func_array(array($obj, 'init'), func_get_args()); } return $obj; }
then, if the initialization method exists, it will call it on creation of the object. the initialization function will be called with all of the parameters that were passed to makeWidget(). to prevent the initialization method from being called again, you could have a initialized boolean flag that is set to true once the init() method is called.
-
Jun 13th, 2010, 03:19 PM
#9
Thread Starter
Hyperactive Member
Re: Factory-esque Design Pattern
I'm seeing now how an abstract Widget class extending the Factory for various properties/methods, and then having each different widget extend the abstract Widget class will work better.
On inheritance: If an abstract Widget class extends the Factory class, and the FirstWidget class extends the abstract Widget class, but Widget has overridden some of the Factory's methods, will the FirstWidget class get the overridden Widget methods, or the Factory methods?
Eg:
PHP Code:
class Factory{ public function myMethod(){ echo "Foo"; } }
abstract class Widget extends Factory{ public function myMethod(){ echo "Bar"; } }
class FirstWidget extends Widget{}
$myWidget = new FirstWidget(); $myWidget->myMethod(); //should say Bar, not Foo... Right?
Is there a way to remove inherited methods further down the ladder? Is there a way I could remove the inclusion of myMethod() from the FirstWidget class altogether, without simply overriding it with a method that throws an exception or something?
-
Jun 13th, 2010, 03:38 PM
#10
Re: Factory-esque Design Pattern
FirstWidget would have Widget's myMethod(), not Factory's.
but, on removing methods? no, that's just how inheritance works. a subclass (a class that extends from another) inherits all public and protected methods. this is one reason why I showed you the example of using debug_backtrace() in this post. you should be able to modify that example to use a proxy constructor in the form of an initialization method to do what you'd like to do, like what I was trying to explain in my last post.
on a side note: are you using PHP >= 5.3? if so, there would be a great solution for this. otherwise, you might have to settle with what I described above.
-
Jun 13th, 2010, 03:50 PM
#11
Thread Starter
Hyperactive Member
Re: Factory-esque Design Pattern
Hmm, looking over all this information, I'm seeing a number of places where I can improve upon and build a better system.
Is this a good class structure though? Am I implementing this well?
The main picture here, is I'm looking to have a parent class oversee certain operational parameters (such as logging, etc.) that are global to all other inheriting classes. In addition to that, it makes sense that the parent class (Factory) be in control of Widget instantiation. The widgets have common methods, which could be inherited from an abstract Widget class as we've discussed, but I'm concerned about the Factory methods being available in the widgets, and I'd like to keep this implementation as clean as possible.
Is there a better way to have the Widgets access otherwise restricted properties of the Factory (global parameters for logging, etc.) as well as have them created by the Factory, without them inheriting any Factory specific functionality, such as global parameter setting methods?
Edit #2: Part of my reasoning here is that when using an IDE with intellisense, I'd like if possible that the Factory specific methods don't register as available methods for a Widget. I know this may seem like a silly reason, but it's a factor I've taken into consideration.
Edit:
on a side note: are you using PHP >= 5.3? if so, there would be a great solution for this. otherwise, you might have to settle with what I described above.
Yes, are you referring to runkit or something like that?
Last edited by tomcatexodus; Jun 13th, 2010 at 04:09 PM.
IWS
-
Jun 13th, 2010, 04:17 PM
#12
Re: Factory-esque Design Pattern
this is an example I made of what I was describing before -- you can set parameters using Factory's setParam() method, and get them using getParam(). are these parameters supposed to be only accessible by widgets, or something? is there any reason why this won't work?
PHP Code:
<?php
class Factory { protected static $params = array(); private function __construct(){} public static function setParam($param, $value){ self::$params[$param] = $value; } public static function getParam($param){ return self::$params[$param]; } public static function makeUserWidget($args){ $obj = new UserWidget; if(method_exists($obj, 'init')){ call_user_func_array(array($obj, 'init'), func_get_args()); } return $obj; } } abstract class Widget { private $_initialized = false; final public function __construct(){ $debug = debug_backtrace(); if(!isset($debug[1]['class']) || $debug[1]['class'] != "Factory"){ throw new Exception("Widgets must be created using the Factory class."); } } final protected function initialize(){ if($this->_initialized == false){ $this->_initialized = true; return true; }else{ return false; } } final public function specialMethod(){ // every Widget will have this specialMethod print_r($this); } } class UserWidget extends Widget { protected $firstNname; protected $age; // no need for a constructor, just the initialization function: public function init($firstName, $age){ // only initialize once if($this->initialize()){ // set fields $this->firstName = $firstName; $this->age = $age; } } public function __toString(){ return "My name is " . $this->firstName . " " . Factory::getParam("lastName") . ", and I'm " . $this->age . " years old.\n\n"; } } header("Content-Type: text/plain"); try { Factory::setParam("lastName", "Smith"); echo Factory::makeUserWidget('Jordan', 23); echo Factory::makeUserWidget('Anne', 22); echo new UserWidget; }catch(Exception $e){ echo $e->getMessage(); } ?>
that will output:
Code:
My name is Jordan Smith, and I'm 23 years old.
My name is Anne Smith, and I'm 22 years old.
Widgets must be created using the Factory class.
anyways, I don't know if this is a good implementation or not because I'm not entirely sure what you're doing. in a recent project, I used a singleton to store global settings -- but this doesn't stop any class from seeing those settings. if you really needed to, you could use the debug_backtrace() trick to stop just any class from returning the object.
-
Jun 13th, 2010, 04:37 PM
#13
Thread Starter
Hyperactive Member
Re: Factory-esque Design Pattern
Your example nearly replicates exactly what I'm looking to do, but there's just a few visibility issues I suppose I'll have to live with:
The singleton Factory is used to store global settings. Via a Factory::setParam() you can set global settings that will be utilized by the Widgets in certain circumstances. These global settings should _only_ be visible to read by Widgets though.
Alternatively, if the Widgets inherit the parameter properties from Factory, setParam() should not be inherited by the Widgets.
Its sort of a double edged sword; If Widgets extend Factory, they inherit Factory specific methods. If Widgets don't extend Factory, parameter properties in Factory need to be made public for Widgets to see them, or at least have a public getter method as your example shows.
Edit: I'm sure everything is pretty clear, but I like to elaborate :P - In short:
The Factory should be able to set global parameters and create Widgets.
The Widgets should be able to read global parameters, but methods/properties of these parameters should not be accessible directly (via a $widget->getParam() method or otherwise) nor should they be able to access the Widget creation methods.
Perhaps I'm trying to achieve the impossible, at least I can get damn close.
I really appreciate all your help with this kows. Any other insight you can share is of course more than welcome.
Last edited by tomcatexodus; Jun 13th, 2010 at 05:19 PM.
IWS
-
Jun 13th, 2010, 05:36 PM
#14
Re: Factory-esque Design Pattern
PHP Code:
<?php
class Factory { protected static $params = array(); private function __construct(){} public static function setParam($param, $value){ self::$params[$param] = $value; } public static function getParam($param){ $debug = debug_backtrace(); if(!isset($debug[1]['object']) || !$debug[1]['object'] instanceof Widget){ throw new Exception("Factory properties are only accessible through Widget classes."); } return self::$params[$param]; } public static function makeUserWidget($args){ $obj = new UserWidget; if(method_exists($obj, 'init')){ call_user_func_array(array($obj, 'init'), func_get_args()); } return $obj; } } abstract class Widget { private $_initialized = false; final public function __construct(){ $debug = debug_backtrace(); if(!isset($debug[1]['class']) || $debug[1]['class'] != "Factory"){ throw new Exception("Widgets must be created using the Factory class."); } } final protected function initialize(){ if($this->_initialized == false){ $this->_initialized = true; return true; }else{ return false; } } final public function specialMethod(){ print_r($this); } } class UserWidget extends Widget { protected $firstNname; protected $age; // no need for a constructor, just the initialization function: public function init($firstName, $age){ // only initialize once if($this->initialize()){ // set fields $this->firstName = $firstName; $this->age = $age; } } public function __toString(){ return "My name is " . $this->firstName . " " . Factory::getParam("lastName") . ", and I'm " . $this->age . " years old.\n\n"; } } header("Content-Type: text/plain"); try { Factory::setParam("lastName", "Smith"); echo Factory::makeUserWidget('Jordan', 23); echo Factory::makeUserWidget('Anne', 22); Factory::getParam("lastName"); //echo new UserWidget; }catch(Exception $e){ echo $e->getMessage(); } ?>
outputs
Code:
My name is Jordan Smith, and I'm 23 years old.
My name is Anne Smith, and I'm 22 years old.
Factory properties are only accessible through Widget classes.
-
Jun 13th, 2010, 05:58 PM
#15
Thread Starter
Hyperactive Member
Re: Factory-esque Design Pattern
Is debug_backtrace() processor heavy? I've read in a few places if I recall correctly, that it is considerably slow.
-
Jun 13th, 2010, 06:10 PM
#16
Re: Factory-esque Design Pattern
it is a bit slow. you could try benchmarking it if you think it's going to be a problem. this is the only way you're going to get the solution you'd like, though.
-
Jun 13th, 2010, 07:24 PM
#17
Thread Starter
Hyperactive Member
Re: Factory-esque Design Pattern
Well, I really appreciate your help kows, and although I'm still planning on making a number of modifications based on what we've discussed, I've got system I was developing working satisfactorily. It's an HTML template engine, not unlike many that already exist. Here's what I've got so far. It's still hugely in the works, especially exception handling, and lots of the features like error reporting, etc., but it does work.
PHP Code:
abstract class Zucklate{ protected static $params = array(); public static function createPage($templatePath, $unlockBoolean = false, $callbackFunction = false){ //validate args return new Page($templatePath, $unlockBoolean, $callbackFunction); } public static function createComponent($componentName, $templatePath, &$parentObject, $unlockBoolean = false, $callbackFunction = false){ //validate args return new Component($componentName, $templatePath, $parentObject, $unlockBoolean, $callbackFunction); } public static function createRegion($regionName, &$parentObject, $callbackFunction = false){ //validate args return new Region($regionName, $parentObject, $callbackFunction); } public static function importParams($paramSource){ //check if $paramSource is array or file //if array, iterate through and implement params //if file, parse, iterate through and implement params } public static function setParam($paramName, $value){ //validate args self::$params[$paramName] = $value; } public static function getParam($paramName){ //validate args return self::$params[$paramName]; } protected static function writeLog($string){ //validate args } } abstract class ZucklateObject extends Zucklate{ protected $data = array(); //object data protected $name; //object name protected $parent; //object parent object reference protected $template; //object template protected $buffer; //object buffer protected $callback; //object callback function reference //override the create methods and throw exceptions when called outside of Zucklate public static function createPage(){ throw new Exception(); } public static function createComponent(){ throw new Exception(); } public static function createRegion(){ throw new Exception(); } public function set($varName, $value){ //validate args if($value){ $this->data[count($this->data) - 1 > 0 ? count($this->data) - 1 : 0]["var"][$varName] = $value; } } protected function compile(){ foreach($this->data as $set){ $buffer = $template = is_array($this->template) ? $this->template[$this->view] : $this->template; foreach($set as $type => $data){ switch($type){ case "region": foreach($data as $name => $value){ $buffer = preg_replace("/@@ region \s name\(" . $name . "\) @@ (.*) @@ end_region \s name\(" . $name . "\) @@/xsi", $value->compile(), $buffer); } break; case "component": foreach($data as $name => $value){ $buffer = preg_replace("/@@ component \s name\(" . $name . "\) @@/xi", $value->compile(), $buffer); } break; case "var": foreach($data as $name => $value){ $buffer = preg_replace("/@@ var \s name\(" . $name . "\) @@/xi", $value, $buffer); } break; } } $this->buffer .= $buffer; } return empty($this->buffer) ? $template : $this->buffer; } } class Page extends ZucklateObject{ protected function __construct($templatePath, $unlockBoolean, $callbackFunction){ if($unlockBoolean !== false){ ${$unlockBoolean} = true; } if($callbackFunction !== false){ $this->callback = $callbackFunction; } ob_start(); include($templatePath); $this->template = ob_get_contents(); ob_end_clean(); } public function render(){ echo $this->compile(); } } class Component extends ZucklateObject{ protected function __construct($componentName, $templatePath, $parentObject, $unlockBoolean, $callbackFunction){
$this->name = $componentName; $this->parent = $parentObject; $this->parent->data[count($this->parent->data) - 1 > 0 ? count($this->parent->data) - 1 : 0]["component"][$componentName] =& $this; if($unlockBoolean !== false){ ${$unlockBoolean} = true; } if($callbackFunction !== false){ $this->callback = $callbackFunction; } ob_start(); include($templatePath); $this->template = ob_get_contents(); ob_end_clean(); } } class Region extends ZucklateObject{ protected $template = array(); protected $view; protected function __construct($regionName, $parentObject, $callbackFunction){ $this->name = $regionName; $this->parent = $parentObject; $this->parent->data[count($this->parent->data) - 1 > 0 ? count($this->parent->data) - 1 : 0]["region"][$regionName] =& $this; if($callbackFunction !== false){ $this->callback = $callbackFunction; } preg_match("/@@ region \s name\(" . $this->name . "\) @@ (?P<views>.*) @@ end_region \s name\(" . $this->name . "\) @@/xsi", $this->parent->template, $region); preg_match_all("/@@ view \s name\((?P<name>.*)\) @@ (?P<template>.*) @@ end_view \s name\((?P=name)\) @@/xsi", $region["views"], $views, PREG_SET_ORDER); foreach($views as $view){ $this->template[$view["name"]] = $view["template"]; } } public function useView($viewName){ //validate args $this->view = $viewName; } public function newInstance(){ //validate args $this->data[] = array(); } }
Any input you may have regarding the class hierarchies, the template engine, or otherwise are greatly appreciated.
-
Jun 13th, 2010, 08:13 PM
#18
Re: Factory-esque Design Pattern
is there an example of how you use it, too?
-
Jun 13th, 2010, 10:16 PM
#19
Thread Starter
Hyperactive Member
Re: Factory-esque Design Pattern
Yea, here's an example:
Your main page. Called page.html
HTML Code:
<html>
<head>
<title>@@var name(pageTitle)@@</title>
</head>
<body>
<h1>@@var name(pageHeader)@@</h1>
<div>@@component name(myComponent)@@</div>
<!-- @@region name(myRegion)@@ -->
<!-- @@view name(results)@@ -->
<h3>Result @@var name(resultValue)@@</h3>
<p>This is a result</p>
<!-- @@end_view name(results)@@ -->
<!-- @@view name(error)@@ -->
<p>There was an error in processing</p>
<!-- @@end_view name(error)@@ -->
<!-- @@end_region name(myRegion)@@ -->
</body>
</html>
This is a component page named component.html
HTML Code:
<h2>This is a component</h2>
<p>@@var name(someText)@@</p>
Finally, this is the page you visit.
PHP Code:
include("zucklate.class.php"); $page = Zucklate::createPage("page.html"); $page->set("pageTitle", "This is my first page"); $page->set("pageHeader", "This is the Page Header!"); $component = Zucklate::createComponent("myComponent", "component.html", $page); $component->set("someText", "This is some text in the component"); $region = Zucklate::createRegion("myRegion", $page); $region->useView("results"); for($i = 1; $i <= 10; $i++){ $region->newInstance(); $region->set("resultValue", "#" . $i); } $page->render();
Gotta finish up on some features, but that might be able to fill in the cracks for detail. I'll give a more comprehensive overview later, I'll have a manual done and the classes will be fully commented.
Edit: Just a note on the Region and Views. You would want to use the alternate view named 'error' (done so by calling $region->useView("error"); ) if something went wrong. So it would be common to have a view for results, a view for messages such as "no results", etc. and you just call the appropriate one, and display it as many times as necessary (for db resultsets etc)
Last edited by tomcatexodus; Jun 13th, 2010 at 10:27 PM.
IWS
-
Jun 13th, 2010, 11:07 PM
#20
Re: Factory-esque Design Pattern
okay, I think you're going about this a bit wrong. I can see why you might want some settings to be globally accessible, but I don't see why you shouldn't have access to them outside of those objects. it could just be a preference thing for you, I guess. but, you don't even use these parameters anywhere, so it's like you're coding them now as something you may want to have in the future. this is generally a bad idea. engineer something to work the way you want it to work now, not how you might want it to work in the future. implementing unused features is a time sink.
I also think that it might be useful just to get rid of the Zucklate class altogether -- at least for what its function is right now. I see no real reason for you to utilize the factory pattern here; you could just create the objects yourself. just name the classes accordingly: ZucklatePage, ZucklateComponent, ZucklateRegion. you can create your components and then add them into the page, or something. I don't know. kind of just rambling. I'm also not sure of the function of a component at all, unless it's just an include, I guess?
experimenting is the best way to learn things, though, so keep at it.
-
Jun 14th, 2010, 01:17 AM
#21
Thread Starter
Hyperactive Member
Re: Factory-esque Design Pattern
I was still coding the parameter interpretation while I posted that :P I was working on logging and a number of other features that are going to be available in this version. That's why it seems.. incomplete. I have written this entirely before, just recently I revamped the parser, the template syntax, and the region/view logic. In progress, I decided that it might be advantageous to go the route I have here so far with the Factory-esque design pattern.
Syntactically, I used to have it as:
PHP Code:
$page = new Page($args); $page->set($args); ...
But opted to go with the factory pattern for controlled object instantiation, as well as the prospect of an overseeing class to manage logging and other features. I just wanted to create a tightly closed system with few potential holes in the implementation.
Components are advanced includes, they have their own data sets so they can include vars, regions, and other components. It might be worthwhile to point out that every object (Page, Component and Region) acts as it's own namespace in a sense. So if you have @@var name(title)@@ in the page, and again within a region on the page, they will be treated differently, and $myPage->set("title", "foobar"); will not interfere with the region's var.
Last edited by tomcatexodus; Jun 14th, 2010 at 01:42 AM.
IWS
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|