linus72982 Posted July 25, 2010 Share Posted July 25, 2010 I have just recently decided to start doing things "correctly" and build my site in OOP PHP instead of procedural (I'm much much much more comfortable with procedural coming from a QBasic start ) and I had a false start last night. I found I was trying to make a procedural program that simply used OOP syntax, it lacked any real benefits of OOP. Anyway, I think I've been set straight and I want to get this right. I've been looking for and studying some design patterns (though I still don't understand them as "overall design patterns", they all seem more like "patterns to implement sections of your site based on what you need to do," but anyway) and I liked the MVC pattern as it makes the most sense to me. If someone can run a sanity check of this architecture for me and tell me if I'm implementing OOP "the right way" and not still hung up on procedural, I would appreciate it. Basically, the site is a "forum" type site in that it stores user inputs and displays them, but it is highly structured for a very specific purpose (I'd rather not say the idea as so far I have yet to see another and I think it has some viral capabilities) - okay, here's the structure: - 1 Parent class: - Ayam (that's the name of the site), this has all the basic functions associated with any sort of entity using the site. - 2 different types of the parent class based on arguments given at construction: - User - Visitor - The parent class has 3 child classes: - Model - Controller - View - Model, Controller, and View change "types" based on whether they are instantiated for use with a User or a Visitor - Model will be the "background functions", as it were, the crunching and manipulation of data - Controller will be the translator between Model and View, naturally it will process input from a user or visitor from the view, pass it to model, model passes back, back to view, things like that - View will display the results of controller-interpreted business logic in a meaningful fashion to the user or visitor - Model functions example: authByToken, getEntityRow (will change tables based on whether it is a User or Visitor), getRecentPosts, things of this nature - Controller functions example: validateLength, escapeInput, formatErrors, getErrorArray, parseEntityRow, etc - View functions example: addTableRow, showEntityPanel, displayPostsByType, drawForm, etc For reference, "entity" is a person on the site, whether User or Visitor. This design should be able to expand if I wanted to add, say, a moderator type for Ayam, and maybe an Administrator type, etc, and still be able to use all the code. The model, view, and controller all have a base set of functions that any entity might use, the different types set at construction either override functions of the parent or have functions unique to themselves. Am I on the right track? Any advice? Thanks for any help. EDIT: I feel like I didn't explain something well enough. The "changing" based on types in reality is simply that I will create either a User or a Visitor object at the beginning of a page and instantiate objects controller, model, and view from different classes depending on whether I send it a User object in construction or a Visitor object. For ease, the file structure might make this clear: - ayam.php - class Ayam - class userAyam extends Ayam - class visitorAyam extends Ayam - ayam_Model.php - class Model - class userModel extends Model - class visitorModel extends Model - ayam_View.php - class View - class userView extends View - class visitorView extends View - ayam_Controller.php - class Controller - class userController extends Controller - class visitorController extends Controller Quote Link to comment https://forums.phpfreaks.com/topic/208803-i-could-use-a-design-sanity-check-new-to-oop/ Share on other sites More sharing options...
linus72982 Posted July 25, 2010 Author Share Posted July 25, 2010 Never mind on the above, I've iterated my design a bit after actually trying to implement it. Anyway, here's what I have now, I hope it works toward my goal of retaining the benefits of OOP: ayam_Spectacle -> my view logic, this isn't actually a class, it's the php code (minimal) that displays pertinent data to the user ayam_Ambassador -> my controller logic, this is the only class Spectacle will instantiate, it is the translator/interpreter/gatekeeper between Spectacle and the business logic. This class contains sections of functions separated by comment blocks for session handling, error handling, validating input, parsing db info passed by mechanism, etc ayam_Mechanism -> my business logic Parent class, this is the version for the basic visitor to my site, this is always instantiated by Ambassador for use by it. This has all the functions every visitor to the site will need such as login/logout, error wrangling, database connections, processing input, etc. ayam_Member - > A child of Mechanism, this further defines additional business logic a logged in member will need in addition to normal visitor functions. ayam_Moderator -> A child of Member, this further defines logic that a moderator will need in addition to normal member and visitor functions. ayam_Administrator -> A child of Moderator, this further defines logic an admin will need in addition to normal moderator, member, and visitor functions. Quote Link to comment https://forums.phpfreaks.com/topic/208803-i-could-use-a-design-sanity-check-new-to-oop/#findComment-1090996 Share on other sites More sharing options...
trq Posted July 25, 2010 Share Posted July 25, 2010 Classes should represent one and only one entity. The idea of jamming login / logout, session handling, error handling & validating input all in one class wreaks of poor design. Quote Link to comment https://forums.phpfreaks.com/topic/208803-i-could-use-a-design-sanity-check-new-to-oop/#findComment-1091043 Share on other sites More sharing options...
linus72982 Posted July 26, 2010 Author Share Posted July 26, 2010 Then I suppose I just don't get the MVC pattern, that's what I was basing it on. It's likely I simply didn't understand what I read about it OOP design seems very abstract. Some tell you to "think outside the box", that's what OOP is all about - but then reel it back in and make sure it conforms to 570,000 different rules that make OO really OO. So, I'm back to an iterated version of my original design, without the hub, with a few lessons learned implemented and a twist: - dbIO - Session - processInput - Validate - Page - Rhythm (my fancy name for config, just constant declarations) So the twist is the Page class. I kept thinking of my pages in terms of entities on the site (visitors, members, moderators, admins) and trying to build objects around that. In building my login handler, I stumbled on making a "page handler" and I rolled with it. Instead of making objects based on who is visiting, I'll just make objects based on the pages and actual things in my site. I have pages, I have forms (input), and sessions, and databases, etc. So, the page class looks something like: error_reporting(-1); require ('ayam_Session.php'); require ('ayam_processInput.php'); public class Page { protected $pageInfo = array(); protected $session; function __construct($section, $page, $postArray) { $this->session = new Session; $this->pageInfo['section'] = $section; $this->pageInfo['page'] = $page; $this->pageInfo['post'] = $postArray; $this->pageInfo['mode'] = $this->session->getV('pageMode'); $this->pageInfo['userInfo'] = $this->session->getV('userInfo'); $this->pageInfo['errors'] = $this->session->getPageErrors($this->pageInfo['page']); $this->pageInfo['sectionObj'] = new $this->pageInfo['section']; } public function getPageInfo() { return $this->pageInfo; } } So you have sections on the site (browse section, login/logout section, user panel section, forum section, etc), each of which is it's own child class of Page. The page will be the page in that section, the individual section classes will know what to do with that info. The mode will change the actual view of the page accordingly (for instance, you might have registrationSuccess mode or showErrors mode, etc). Post is any post data sent to the page. The section object will invoke the appropriate child class for use. The others are self-explanatory. There aren't many parent functions yet but I'm sure there will be a few more as I go and realize I need them. Please tell me I'm at least close to being on the right track here. At first this smacked of the hub I made before, but I realized it isn't, I only create objects as I need them and depending on the page the user is on. With this handler I was thinking it would be easy to implement different sections or pages in existing sections. I'm about this close to just sticking with procedural J/K, I appreciate all the learning and help. Thanks for any advice. Feel free to just give up on me and ignore this post, heh. Quote Link to comment https://forums.phpfreaks.com/topic/208803-i-could-use-a-design-sanity-check-new-to-oop/#findComment-1091127 Share on other sites More sharing options...
AtlasC1 Posted August 17, 2010 Share Posted August 17, 2010 This is the first time I've seen the actual page/site as its own object. I've been doing OOP PHP programming for about 4 months now; is this common practice? Normally I take a PHP/Procedural combination, the code seems a lot less complicated. I.E: I would have a standard PHP page with HTML elements for the layout. Then, I would create a Forum object and insert that into the page. The forum object would then have classes within itself (e.g., users, posts, etc.). Maybe I should start rethinking things too... -jm Quote Link to comment https://forums.phpfreaks.com/topic/208803-i-could-use-a-design-sanity-check-new-to-oop/#findComment-1100377 Share on other sites More sharing options...
ignace Posted August 17, 2010 Share Posted August 17, 2010 Although you took a good turn with the Page class you'll want to zoom out and group some related functionality (high cohesion) together. Like: Controller: class UserController extends BaseController { private $storage = null; // DataAccessObject or something else function add($options) { $user = UserFactory::create(); $user->setEmailAddress($options->email_address) ->setPassword($options->password); $this->view->setFaultCode($this->storage->save($user), $options); } function edit($options) { $user = $this->storage->findByEmailAddress($options->email_address); $this->view->setFaultCode($this->storage->save($user->modify($options)), $options); } function remove($options) { $this->view->setFaultCode($this->storage->delete($options->email_address), $options); } } View: <?php if($this->hasFaultCode()): ?> <p class="error"><?php print displayNiceError($this->getFaultCode(), $this->getOptions()); ?></p> <?php endif; ?> View Helper: function displayNiceError($code, $options) { $message = SomeService::getMessageFor($code); return $translator->translate($message, $options); } Something along those lines, I'm partially experimenting here with possibilities. Quote Link to comment https://forums.phpfreaks.com/topic/208803-i-could-use-a-design-sanity-check-new-to-oop/#findComment-1100493 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.