SitePoint Sponsor |
|
User Tag List
Results 51 to 75 of 101
-
Feb 7, 2005, 13:04 #51
Okey, I'll start up a new thread on "best practices" . To get "on" topic again (or within scope).
I still think the best aproach is(after much reading - mostly on java.sun.om, this forum, etc.) a pretty classic MVC with something that goes like this:
HTTP/CLI Request > RequestObject(Holds Request Data) > Front Controller > Pre-Intercepting Filters(Including Action specific) > Application Controller > Action Chain > Action(Untill the action chain is clear) > Application Controller Wrap up(Cleaning up objects, etc.) > View Render > Post-Incercepting Filters(Including Action specific) > Front Controller Wrapup(Cleaning up objecs, etc.) > exit();
Now I'm going to take some time to figure out how to link all these together, what config files are needed, how to build huge "Main"-pages (I have to look into the WACT aproach McGruff - Is there any other way to do it), etc.
What do you guys think about this aproach?(While i like trini0's idea about everything as one big filter chain, I have problems visualising how to build huge pages with that aproach because all the filters are unaware of eachother. To pass data between them they need to know about eachother).
-
Feb 7, 2005, 13:30 #52
- Join Date
- Jan 2003
- Posts
- 5,748
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
On the point of having mini actions to build a page from smaller parts (of the whole) I too have yet to find a (suitable) solution?
I had the idea of CoR which would need to be configurable... Until I thought of making the CoR observable, as where McGruff is going with what WACT is doing though with the composite instead.
But it's only a thought process at the moment, not had the time to put any script into practice
The difference between using the CoR and the Composite is that the CoR could act as executables (actions) whereas the Composite couldn't (without some help)?
Ideas is what these are at the moment folks
-
Feb 7, 2005, 13:33 #53Off Topic:
Dr Livingston: I was thinking(or well, did =p) about moving this subject on how to structure larger pages with MVC that requires many small components to another thread, you can find it here: MVC - How to handle big pages with many different parts? - as I belive this is out of scope for this thread.
-
Feb 7, 2005, 15:06 #54
- Join Date
- Jan 2003
- Posts
- 5,748
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Okay, may be posting in the wrong thread now I'm not sure? This is what I was working on before Observers came into the discussion, example script below
PHP Code:// $request = $this -> request -> getParameter( 'action' );
$request = 'view'; // temp
$chain = new ChainOfResponse( 'View' ); // News, Articles, whatever
$chain -> attach( 'Create' );
$chain -> attach( 'Modify' );
$chain -> attach( 'Delete' );
$chain -> attach( 'Search' );
$chain -> process( $request );
class ChainOfResponse {
private $count = -1;
private $handlers = array();
public function __construct( $handler ) {
// initial handler ??
$this -> handlers[++$this -> count] = new $handler;
}
public function attach( $handler ) {
$this -> doAttach( new $handler );
}
public function process( $request ) {
$handle = $this -> handlers[0];
$handle -> handleRequest( $request );
}
private function doAttach( $handler ) {
$temp = $this -> handlers[$this -> count];
$temp -> setHandler( $handler );
$this -> handlers[++$this -> count] = $handler;
}
}
class View /* implements an interface ... */ {
private $handle;
public function __construct() {
}
public function setHandler( $handle ) {
$this -> handle = $handle;
}
public function handleRequest( $request ) {
if( $request == 'view' ) {
echo( 'execute view action' );
} else {
$this -> handle -> handleRequest( $request );
}
}
}
class Create {
private $handle;
public function __construct() {
}
public function setHandler( $handle ) {
$this -> handle = $handle;
}
public function handleRequest( $request ) {
if( $request == 'create' ) {
echo( 'execute create action' );
} else {
$this -> handle -> handleRequest( $request );
}
}
}
class Modify {
private $handle;
public function __construct() {
}
public function setHandler( $handle ) {
$this -> handle = $handle;
}
public function handleRequest( $request ) {
if( $request == 'modify' ) {
echo( 'execute modify action' );
} else {
$this -> handle -> handleRequest( $request );
}
}
}
class Delete {
private $handle;
public function __construct() {
}
public function setHandler( $handle ) {
$this -> handle = $handle;
}
public function handleRequest( $request ) {
if( $request == 'delete' ) {
echo( 'execute delete action' );
} else {
$this -> handle -> handleRequest( $request );
}
}
}
class Search {
private $handle;
public function __construct() {
}
public function setHandler( $handle ) {
$this -> handle = $handle;
}
public function handleRequest( $request ) {
if( $request == 'search' ) {
echo( 'execute search action' );
} else {
die( 'Something bad has just happened' );
}
}
}
-
Feb 7, 2005, 15:17 #55
Dr Livingston: You're talking about the Chain of Responsibility that McGruff mentioned? While at first I thought this was a great idea, I'm doubting it now because it locks you so tight, when you have started the chain there is _no_ way out of it( except die(); ). While i think the idea is good, it needs to be implemented on a lower level - but maybee this is what you just did? I'm starting to consider my ActionChain a Chain of Exectution(not Responsibility, fine but important distinction). After reading some on java.sun.com I feel that the more traditional way to go is the right one afterall. But I'm still not convinced. If you look at this post by me in this thread, where would you put your Chain in the exection order I wrote down there? (I read this post now, god I sound so hostile - not my intent mate)
-
Feb 7, 2005, 15:31 #56
- Join Date
- Dec 2002
- Location
- Colorado, USA
- Posts
- 79
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
I worked on developing a CoR framework and even got to some working examples, but what did it for me was the fact that any programmers coming behind me would have been totally confused. In principle, it's a great idea, but it is very tough to have a easily understandable framework when using CoR. People have trouble with MVC, and that is one of the most basic of patterns. I mean, I have been programming for a few years and I don't completely understand MVC. I end up using a watered down version that suits my particular task.
Now, one mention I will make that might interest anyone reading this thread was to take the CoR problem away from forcing PHP into an OO box. Doing the
PHP Code:$chain->attach("FirstAction");
$chain->attahc("SecondAction");
$chain->attach("ThirdAction");
For example, take the following URL:
Code:http://www.foobar.tld/index.php?pg=/cache/bookmark/showBookmarks
-
Feb 7, 2005, 15:44 #57
- Join Date
- Jan 2003
- Posts
- 5,748
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Thr,
No offence taken I'm going to go back and read the thread from the stard again as I'm confused about your Chain of Execution? I need to refresh my mind I think
The script I posted is something I did earlier this week and had been on my mind for a while, so it will no doubt morph into something else I hope. On the point of MVC being the most basic pattern I agree, it is pretty simple.
But watered down or not I think the more important thing is how (and what) you implement along side MVC? MVC is pretty basic and as such it is limited in what can be achieved with it (MVC) alone I think... So we have Decorators, CoRs, et al just bouncing about yes?
...
-
Feb 7, 2005, 15:52 #58
This is what I got for application flow, for a standard MVC Implementation - does it seem to be quite correct?
- >HTTP/CLI Request (Mapped to a single Request Object)
- >Request (Holds the Request specific Data and the Controller)
- >Front Controller (Looks at the incomming request and applies Intercepting Filters and Application Controller)
- >Intercepting Filters (Filters that manipulate/look at the request and take aproiate action(Cleaning Request Variables,Authentication,Logging,Cache,Validation,Session))
- >Application Controller (Looks at the mapping and loads the Action Chain and Actions, and starts processing the Chain)
- <>Action (One single action reqeusted by the user, repeated untill the Action Chain is empty)
- <Application Controller (Shuts down the Application Controller)
- <Intercepting Filters (Closes down filters initiated in the (Pre) Intercepting Filters Part)
- <Front controller (Releases the application controller)
- <Request (Releases the front controller and all asociated objects)
- <HTTP/CLI Response (The response is written to the Client, application shutdown)
> = Start/Use
< = Shutdown
While I agree that MVC as a pattern is quite easy to understand, it's damn much harder to implement successfully. Especially when you mix Intercepting Filter, Chain of Responsibility, Decorator, Composite View, etc. into it
-
Feb 8, 2005, 17:31 #59
This is a list of classes / relations I came up with today/tonight, any comments?
+ = Public
* = Protected
- = Private
SystemObject
---- Methods ------ + __construct()
- + __destruct()
- + __toString() : string
- + __clone() : void
- + __equals() : boolean
Request extends SystemObject, implements Singleton
--- Properties ---- * action : string
- * controller : FrontController
- * instance : Request
- + __construct()
- + __destruct()
- + getAction() : string
- + getController() : FrontController
- + instance() : Request
HTTPRequest extends Request
--- Properties ---- * method : string
- + __construct()
- + __destruct()
- + string getMethod() : string
CLIRequest extends Request
--- Properties ---- * environment : string
- + __construct()
- + __destruct()
- + string getEnvironment() : string
FrontController extends SystemObject, implements Singleton
--- Properties ---- * action : string
- * mapping : Mapping
- * filterChain : InterceptingFilterChain
- * instance : FrontController
- + __construct([string action])
- + __destruct()
- + perform() : void
- + instance() : FrontController
- - buildMapping(string action) : Mapping
- - buildFilterChain(Mapping mapping) : void
Mapping extends SystemObject
--- Properties ---- * childs : VectorList
- * filters : VectorList
- * redirects : VectorList
- * actionName : string---- Methods -----
- + __construct(string actionName,[childs VectorList][,filters VectorList][,redirects Vectorlist])
- + __destruct()
- + getChildsIterator() : ArrayIterator
- + getRedirectsIterator() : ArrayIterator
- + getForwardsIterator() : ArrayIterator
- + getActionName() : string
InterceptingFilter extends SystemObject
--- Properties ---- * name : string
- + __construct()
- + __destruct()
- + start() : void
- + stop() : void
VectorList extends SytemObject implements IteratorAggregate
--- Properties ---- * vector : array
- + __construct()
- + __destruct()
- + size() : int
- + remove() : void
- + get() : mixed
- + exists() : boolean
- + add(mixed item) : void
- + addArray(array itemArray) : void
- + getIterator() : ArrayIterator
InterceptingFilterChain extends VectorList
---- Methods ------ + add(InterceptingFilter filter) : void
FIFOStack extends SystemObject
--- Properties ---- * stack : array
- + __construct([array stack])
- + __destruct()
- + peek() : mixed
- + pop() : mixed
- + size() : int
- + push(mixed value) : void
- + pushArray(array array) : void
LIFOStack extends FIFOStack
---- Methods ------ + peek() : mixed
- + pop() : mixed
ApplicationController extends SystemObject implements Singleton
--- Properties ---- * mapping : Mapping
- * actionStack : FIFOStack
- * instance : ApplicationController
- + __construct()
- + __destruct()
- + perform() : void
- + instance() : ApplicationController
- + setMapping([Mapping mapping]) : void
- - buildActionStack(Mapping mapping) : void
Action extends SystemObject
--- Properties ---- * resultSet : ActionResultSet
- + __construct([ActionResultSet resultSet])
- + __destruct()
- + perform() : ActionResult
ActionResult extends SystemObject
--- Properties ---- * type : string
- * data : mixed
- + __destruct()
- + setResult(mixed data) : void
- + getResult() : mixed
- + setType(string type) : void
- + getType() : string
ActionResultSet extends VectorList
---- Methods ------ + add(ActionResult item) : void
####### Application Flow(For HTTP Request) #######
(index.php?action=ListUsers)
$request = HTTPRequest::instance();
$controller = $request->getController();
$controller->perform();
(inside FrontController::perform())
1. Build Mapping
2. Set up FilterChain
3. Start Filters
4. Create instance of ApplicationController
5. Set Mapping in ApplicationController and do ApplicationController::perform()
6. Handle result from ApplicationController
7. Stop Filters
8. Unset Filters, Mapping and Application Controller
(inside ApplicationController::perform())
1. Build ActionChain
2. Loop ActionChain and pass results around as needed
3. Return result of completed ActionChain
- + __construct()
-
Feb 8, 2005, 20:42 #60
- Join Date
- Sep 2003
- Location
- Glasgow
- Posts
- 1,690
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
I didn't follow all of that. It doesn't help that I don't know any php5.
It's good that you've considered a ServiceLayer for different clients (HTTP/CLI).
Why are you making several objects singletons? I don't think you need to do this. A tap on the back of the hand if it's to make them "global"
I'm also wondering about the SystemObject. It looks like there are several classes with quite different responsibilities all inheriting the same superclass which makes me twitchy. Also, would you want to clone an object which you have made a singleton?
How are you thinking about Request? I'm not sure if this should contain a FrontController. Objects ought to be tightly focussed (for one thing they'll be harder to test if not) and Request, as I see it, is basically just the input received from the client. Some additonal meaning might be added to this as it passes through the system. For example, a user id could be set here when (or rather if) authentication is carried out. Validated GPC values would be stored here with invalid ones set to null (if other objects only access the validated input rather than raw GPC dodgy data never gets near the app). Request wouldn't do the validation, although you could pass in an object which does - either that or pass the request through the validator code.
Since this kind of Request will get passed around almost everywhere, it will be tempting to use it as a dumping ground for everything including the kitchen sink. Keep it cohesive. I think it's reasonable to add something like a user id since this is an aspect of client request state but don't use it, for example, to pass a db conn around (I'm sure you wouldn't).
From this perspective, Request shouldn't know about FrontController. How can a client know if you are using FrontController or a pure PageController set up? And, what would happen if you decided to switch to PageControllers?
-
Feb 9, 2005, 00:30 #61
- Join Date
- Aug 2004
- Location
- California
- Posts
- 1,672
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
That was too long to follow and I usually use fewer classes.
From this perspective, Request shouldn't know about FrontController.PHP Code:$controller = new FrontController(new Request());
$controller->execute();
How can a client know if you are using FrontController or a pure PageController set up? And, what would happen if you decided to switch to PageControllers?PHP Code:$controller = new PageController(new Context(new Request()));
$controller->execute();
Christopher
-
Feb 9, 2005, 02:42 #62
McGruff: While reading your reply I say that you make some good points - this was only a first design that I thought up yesterday. I'll try to cut out the unneeded parts and make in to a UML Diagram instead(easier to follow) - didn't have any good application for make UMLs last night, got any tips?
arborint: Yes, thanks - I'll probably go that way instead (passing the request to the controller instead of the other way around).
-
Feb 9, 2005, 06:19 #63
- Join Date
- Jun 2003
- Location
- Iowa, USA
- Posts
- 3,749
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by thr
People say good things about ArgoUML as well.
-
Feb 9, 2005, 07:11 #64
- Join Date
- Sep 2003
- Location
- Glasgow
- Posts
- 1,690
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by arborint
-
Feb 9, 2005, 09:19 #65
Here comes (another) diagram/idea from me that is what has evolved in my mind during the last few days. What do you think?
-
Feb 9, 2005, 10:56 #66
- Join Date
- Aug 2004
- Location
- California
- Posts
- 1,672
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Anything common to all requests could also be put in a PageController superclass. There's very little difference between this design and a FrontController, just that apache or etc has mapped the request to the ApplicationController rather than FrontController doing the mapping.Christopher
-
Feb 9, 2005, 11:27 #67
- Join Date
- Jan 2003
- Posts
- 5,748
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Thr,
I think your diagram describes things as they should be, bar one thing? You have the Application Controller coupled to the Front Controller...
So the purpose of the Front Controller is to decide which action to consume, so I'm assuming your leaving this up to the Application Controller then?
The stack looks like your Chain of Execution as well I assumeEarlier to your reply, does your Chain of Execution execute all the handlers in the chain, as apposed to a CoR which may only execute one handler of many. Think I got that part right now
-
Feb 9, 2005, 11:31 #68
I'm working on a more detailed model, with more comments, etc. right now.. i stil dont have a decent UML/Design program som i'm using a normal drawing application, ~30mins and it'll be done
-
Feb 9, 2005, 12:06 #69
- Join Date
- Sep 2003
- Location
- Glasgow
- Posts
- 1,690
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by thr
Originally Posted by Dr WidowBobLivingstonMaker
A FrontController has to map a request to an ApplicationController ie something which knows how to handle the current request type. That's its unique, defining responsibility. It has to know the API.
-
Feb 9, 2005, 12:11 #70
Here is my hopefully final model, and the one I will build my test MVC implementation from - comments?
-
Feb 9, 2005, 12:56 #71
For now I think I'll settle for a XML-Mapping as it's easier to read for the human mind. I'll create a Mapping-Object/Wrapper so I can switch the Mapping to a PHP Array if I want to, here's the basic layout:
Code:<?xml version="1.0" encoding="iso-8859-1"?> <action> <name>Testing</name> <subactions> <sub>PrintArray</sub> <sub>PrintString</sub> </subactions> <filterlist> <filter>SessionFilter</filter> <filter>OBFilter</filter> <filterlist> <view>TestingView</view> <failure> <type>ClientRedirect</type> <target>index.php?action=Default</target> </failure> </action>
-
Feb 9, 2005, 15:00 #72
- Join Date
- Jan 2005
- Location
- Sydney
- Posts
- 43
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by thr
-
Feb 9, 2005, 15:10 #73
Originally Posted by dylanegan
This is just for learning and fun :]
-
Feb 9, 2005, 16:27 #74
If someone could care to comment on this example code i wrote down tonight(took about 2hours or so) i would be happy. As with the last example I put up. This is not production code, this is "i-wouldnt-even-use-this-as-an-bad-example"-code, it's so bad - bad examples look good. I just wrote it realy quick to get a working example of the program flow, here goes(notice the name on 2 of the actions "printarray" and "printstring".. they are just mock stuff to return some data.. the names are just bogus):
-
Feb 9, 2005, 18:24 #75
- Join Date
- May 2004
- Posts
- 142
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
This is not production code, this is "i-wouldnt-even-use-this-as-an-bad-example"-code, it's so bad - bad examples look good.
Bookmarks