Jump to content

Back to basics....


redbullmarky

Recommended Posts

Hi all

Right, I seem to have hit a brick wall. The more I read different ideas of OOP, and the more I see it implemented, the more confusing things get - so in a nutshell, I'm trying to "forget" a little, and go back to basics in order to get a CMS I'm building off the ground properly.

 

The biggest issue is keeping classes as independent as possible, but knowing what to set up, where, how, what to pass to constructor, etc. I'll use my current project as an example. I'm sure I'll need the following:

 

- session class

- database class

- request class (for handling input variables, files, URL, IP's, etc)

- template class (for rendering templates+tags)

- a "page/object" class (for loading a page from the DB with its vars/settings to be inserted into the template - returns the final output, though i'm considering returning a "response" object that can handle other MIME types such as RSS, XML, images, etc)

- a config class for handling site-wide configuration.

 

Now - I want to keep things flexible and very simple. My questions:

 

1, my session class may or may not require the use of a DB, depending on whether I need to store sessions in the DB, or whether I wish to use PHP's built in session handling.

 

2, how should my config object be passed around/accessed? Singleton? Config::getInstance() ? via a registry?

 

3, my page object needs a simple constructor, ideally just taking either the request URL, or a request object - as i'll need to be able to "spoof" requests from time to time from other parts of my application. What would be the best way to set up the constructor here? It'll need all of the classes mentioned previously.

 

 

as it stands at the moment, my constructor arguments are a mess, dependent classes are instantiated/accessed all over the place (sometimes passed, sometimes instantiated in the constructor or where needed, etc) and things look far from flexible - ie, classes look a little too dependent on eachother.

if anyone has any advice on how the above classes might sit together nicely, whilst still giving me the flexibility long term, that would be great.

 

Using PHP 5.1

 

Cheers!

Mark

Link to comment
Share on other sites

The other questions are hard to answer without better/deeper understanding of your system and it's architecture.

 

#2: Use a registry - especially if it's initialize in the application entry point. I Use the registry for strictly that purpose giving global access to centralized objects.

 

Authentication

Database

etc, etc...

Link to comment
Share on other sites

1) Simply abstract database accesss and apply a little polymorphism. E.g. SessionObject (abstract) SessionDBObject, SessionMemcachedObject and SessionFileObject.

 

2) Sort of echo above. Instead of accessing the configuration troughout the app, use it to initialize Factories and Singletons. This should make packes a little more autonomous. I've personally grown to like a modified version of Singleton: an object that throws an exception when you try to access it more than once. A simple static flag does the trick.

 

3) I'm not so sure about the Page object as a concept. IMO, you need to rethink it. Why would it need instances of all the other classes you mentioned?

Link to comment
Share on other sites

re number 3:

 

in my thinking, my Page object I guess would represent a row data gateway to the page's DB record. The page's DB record holds the values that are embedded in my templates (eg Title, Author, Body, etc), as well as stuff like parent id, etc. so ideally my page class would read the relevent page data, render the template and return the actual output.

 

thanks guys so far.

Cheers

Mark

Link to comment
Share on other sites

Throwing an exception when trying to access a singleton is pretty bad IMO.  You don't create a singleton because it is only going to be created once but because you one need one instance of it otherwise you are kinda limiting yourself with that object.  I personally think you should also throw back the existing instance of the object if it exist.

Link to comment
Share on other sites

Throwing an exception when trying to access a singleton is pretty bad IMO. 

 

Bad... Right.

 

You don't create a singleton because it is only going to be created once but because you one need one instance

 

It's not really a Singleton.

 

of it otherwise you are kinda limiting yourself with that object[/q].

 

Which is exactly the intent.

 

A Singleton has the nasty side effect of making it too damn easy to litter your app with calls at it, since it is static and thus globally available.

 

Only allowing a single fetch of the object prevents this and keeps dependencies more transparent.

 

Basically it's just a slightly different way of instantiating objects. A very limiting one. It's just defensive programming.

 

I personally think you should also throw back the existing instance of the object if it exist.

 

If you don't mind I'll decide on the workings of my code myself, thank you very much. :D

Link to comment
Share on other sites

If you don't mind I'll decide on the workings of my code myself, thank you very much. Cheesy

 

Hey man, code how ever you like.  My way to to give the programmer the power of doing what they like and trusting them to know how to use the code instead of preventing them from doing something that is not always bad.  We just have 2 different ways of programming, and both work just fine each programmer.

Link to comment
Share on other sites

If a client developer wants to be stubborn any use my pseudo-Singleton as a regular one, he still can. Just decorate the pseudo with a regular one.

 

It's not about limiting the client developer, it's about enforcing a components' intended use. If you (the client dev) want to be stubborn and use a component for something it wasn't build for, you have to know what you're doing.

Link to comment
Share on other sites

Sure, sorry about the intrusion.

 

From what I can gather, it's actually a Page Controller, not a Row Data Gateway: a class having responsibility for controlling a single presentation (a single 'page').

 

Maybe I misunderstood, but since you didn't mention any domain layer, nor control components: I'm assuming both types of logic are cramped into the Page hierarchy, together with the data access. A Row Data Gateway doesn't concern itself with domain and control logic, thus wouldn't need access to the other classes you summed up.

 

Page Controllers can work adequately, as long as you don't have too many different presentations and relatively simple business logic. With a reasonably simple CMS you should already notice some of it's ill effects, most notably repeating logic.

 

IMO, simplicity and flexibility don't usually go hand-in-hand.

 

If you're looking for suggestions, I would use a simple implementation of the classic Controller/Domain Object/DAO or Data Mappper combo. It won't be as simple as you had in mind, but will be flexible.

Link to comment
Share on other sites

1) Simply abstract database accesss and apply a little polymorphism. E.g. SessionObject (abstract) SessionDBObject, SessionMemcachedObject and SessionFileObject.

An alternative (and my personal preference) would not be to have an abstract architecure like the above, but to delegate the accessing functionality to a child object, rather than a child class.
$session->setAccessor(new FileAccessor('/foo'));

or

$session->setAccessor(new DBAccessor('mysql://username/pass/db'));

:)

2) Sort of echo above. Instead of accessing the configuration troughout the app, use it to initialize Factories and Singletons. This should make packes a little more autonomous. I've personally grown to like a modified version of Singleton: an object that throws an exception when you try to access it more than once. A simple static flag does the trick.

We've already had somewhat heated discussions on my views of singletons. :) So I won't go into detail, but in summary, they break encapsulation, make testing difficult, and are just altogether icky. :)
Link to comment
Share on other sites

An alternative (and my personal preference) would not be to have an abstract architecure like the above, but to delegate the accessing functionality to a child object, rather than a child class.

$session->setAccessor(new FileAccessor('/foo'));

or

$session->setAccessor(new DBAccessor('mysql://username/pass/db'));

:)

 

I'll give you that one. It can even be used as more than a simple Bridge, when you reuse the Accessor interface to serve other clients as well. The first example that springs to mind is an object caching package.

 

Note: I looked that up and it turns out it is already described in GoF[155] (Bridge Implementation), issue 3.

 

But, the man asked for simple, and polymorphism is the first thing that springs to mind in that case. I know, it's not really more complicated.

 

We've already had somewhat heated discussions on my views of singletons. :) So I won't go into detail, but in summary, they break encapsulation, make testing difficult, and are just altogether icky. :)

 

Brussels sprouts are icky, Singletons should just be used with moderation and caution. ;D

 

Although I have to admit, I have become a little more wary of Singletons. Thus my new personal favorite way to ensure a single instance without having globally available instances: "Singlestantiators"... :P

 

class Singlestantiator {

private static $instantiated = false;

public function __construct(){
	if(self::$instantiated){
		throw new SomeException('Too late buddy, somebody beat you to it.');
	}
	self::$instantiated = true;
}
}

 

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.