FAQ
I'm a little confused about Catalyst's separation of Controller vs
Model code. My understanding of the strictest version of the MVC
pattern is:

- The Controller accepts input from the outside (usually the
user) and causes changes to the Model.
- The Model stores state and, when updated by the Controller,
informs the View that it needs to redraw.
- The View displays the current state of the Model.

Is this more-or-less correct, or have I misunderstood the pattern?

I realize that, in real-world implementations, these concerns are
less completely separated...e.g. the Model may cause changes in its
own state, and communication may flow in more paths than those listed
above.

What do the rest of you see as the dividing line between a
Catalyst::Model and a Catalyst::Controller object? When you are
creating a new object, how do you decide which hierarchy it belongs in?


--Dks

Search Discussions

  • Dominique Quatravaux at Jun 2, 2005 at 5:59 pm

    David Storrs wrote:
    What do the rest of you see as the dividing line between a
    Catalyst::Model and a Catalyst::Controller object? When you are
    creating a new object, how do you decide which hierarchy it belongs
    in?
    Personally I find the following rule of thumb useful (of course it's
    not a silver bullet): if it could be used in a non-Web environement
    (for example in a crontab), then it is part of the Model. If not, it
    is probably part of the Controller.

    You may find more enlightenment on the Portland Pattern Repository
    Wiki: I found it to be an excellent resource for this kind of discussion.

    http://c2.com/cgi-bin/wiki?ModelViewController

    - --
    Dominique QUATRAVAUX Ing?nieur senior
    01 44 42 00 08 IDEALX
  • Perrin Harkins at Jun 2, 2005 at 6:56 pm

    On Thu, 2005-06-02 at 11:47 -0400, David Storrs wrote:
    What do the rest of you see as the dividing line between a
    Catalyst::Model and a Catalyst::Controller object? When you are
    creating a new object, how do you decide which hierarchy it belongs in?
    This division in web-based MVC development is frequently a subject of
    debate. Most tools break it down in the simplest way, where the model
    is essentially just the database access objects. MVC purists complain
    that this causes a lot of logic to end up in the controller, which was
    supposed to be nothing more than translating HTTP to method calls (i.e.
    the controller should not need to know about your problem domain). The
    usual fix suggested is to make what are sometimes called "action
    classes" which contain the logic you would otherwise put in a controller
    but are part of the model instead. The action classes are coded to be
    independent of the web environment so they can be used elsewhere.

    As an example, for a restaurant reservation system you might have
    classes representing tables and people, and action classes for things
    like finding a free table, booking a reservation, etc. These make sense
    for situations where they need to act on multiple database objects in a
    complex way.

    The problem with this approach is that it becomes very annoying when
    working on simple actions, especially the kind of CRUD stuff that
    Catalyst and Maypole have done a good of automating. But maybe you can
    just call the CRUD automation "action classes" and go to bed early...

    I plan to touch on this in my talk at YAPC in Toronto about MVC
    frameworks, but probably won't have enough time to go into it deeply.

    - Perrin
  • Justin Tocci at Jun 6, 2005 at 5:52 am
    Hi all. I don't think MVC is adequate. Catalyst works something like
    this:

    *start*
    --> request from browser
    --> http handler (e.g. apache)
    --> Controller
    <--> Model
    --> Controller
    --> http handler
    --> browser
    *end*

    Real quick and simple, I'd like to see Catalyst take a step in the
    direction of separating out the business logic from the entire
    design. What's wrong with MVC is that business logic has to go
    somewhere, some will make room in the model, some in the controller,
    probably all three in a large application, but it could be separated
    out entirely.

    *start*
    --> request from browser
    --> view handler (e.g. apache)
    --> Controller <--> bus. logic expressions component
    <--> Model
    --> Controller
    --> view handler
    --> browser
    *end*

    Since business logic rightly involves model, view and controller,
    it's ok to put code in the business logic that says to display a date
    a certain way, or multiply a certain field by pi before displaying
    it. Some examples of business logic I'd like to see separated out
    into a separate file would work like this; "if user type is admin,
    then allow delete action" (this would affect all pages for admin
    users), "if page type is edit and user type is sales then show edit
    record button", "if country is usa, then date format is mm-dd-yy".

    You could quickly write a base set of rules for admin, sales, office,
    accounting, etc... giving groups permissions on what tables they can
    and can't see, edit, or administer. Or, write a base set of rules for
    display by the user's language. What's "edit" in Spanish anyway?

    One beauty of this scheme is that you could probably work out a way
    to re-load the rules on the fly, allowing for lightning-quick
    development and testing. Another is that you could go many miles
    further on standard CRUD views with a good base of default rules.
    Default rules would come up with good display names for columns by
    changing under-bars to spaces and capitalizing words. On top of that
    you could single out exceptions by writing rules that would override
    the default, for instance, acronyms would need to have rules like,
    "if column name is nasa, then display name is 'NASA'", note that a
    rule like this is good for any page or situation. Some rules will
    start "if user is sales" but they don't all have to. Therein lay the
    power of rule-based rapid application development, a rule has the
    scope you give it. It can affect the entire application or just a
    single component in a very particular situation.

    Perhaps the rules should be separated out further. One rule file each
    for model, view and controller? This might speed development by
    allowing different formats. Not that anyone's interested.

    The adept may recognize that I miss my rule file from WebObjects, but
    the truth is, he who can deliver this functionality in a simple way
    with Perl would gain fame, fortune and honor before all. I have
    abandoned WebObjects because of all the things wrong with it, but
    this one feature kept me at it for a very long time.

    I will commit 100 hours to the project over the next 90 days, a two
    page summary of how it could work in 14 days, coordinate the
    development of the default set of rules, and whatever else I can fit
    into my schedule if a project were to take on a design goal like
    this. I'll, yes, I'll even, yes, I'll even write documentation! Ugh!


    justin tocci
    fort wayne, in
  • David Storrs at Jun 6, 2005 at 6:56 am

    On Jun 5, 2005, at 11:54 PM, Justin Tocci wrote:

    Hi all. I don't think MVC is adequate. Catalyst works something
    like this:

    *start*
    --> request from browser
    --> http handler (e.g. apache)
    --> Controller
    <--> Model
    --> Controller
    --> http handler
    --> browser
    *end*
    Urmm...well, ok, that'll do for a first-order approximation. Don't
    forget about Views (not shown), and the fact that Catalyst may have
    multiple Controllers and/or Models.

    Real quick and simple, I'd like to see Catalyst take a step in the
    direction of separating out the business logic from the entire design.
    Ummm...huh? Separation of business logic from design is the entire /
    point/ of the MVC pattern, which Catalyst implements.

    What's wrong with MVC is that business logic has to go somewhere,
    some will make room in the model, some in the controller, probably
    all three in a large application, but it could be separated out
    entirely.
    I am not sure that you are really familiar with the MVC pattern. The
    Platonic ideal MVC system has all business logic in the Controller,
    all state in the Model, and all presentation is handled by the View.
    How much more separated out can the business logic get? Or are you
    saying that it could be stored off in a config file (or DB)
    somewhere? If so, you program needs to interact with those business
    rules somehow, so who's job is it to pull those rules in and
    interpret them?
    *start*
    --> request from browser
    --> view handler (e.g. apache)
    --> Controller <--> bus. logic expressions component
    <--> Model
    --> Controller
    --> view handler
    --> browser
    *end*

    Since business logic rightly involves model, view and controller,
    it's ok to put code in the business logic that says to display a
    date a certain way, or multiply a certain field by pi before
    displaying it.
    I don't know that anyone was arguing that point...and it seems to
    come rather out of left field. Would you like to clarify?
    Some examples of business logic I'd like to see separated out into
    a separate file would work like this; "if user type is admin, then
    allow delete action" (this would affect all pages for admin users),
    "if page type is edit and user type is sales then show edit record
    button", "if country is usa, then date format is mm-dd-yy".
    See previous comment about "who pulls this in?"
    You could quickly write a base set of rules for admin, sales,
    office, accounting, etc... giving groups permissions on what tables
    they can and can't see, edit, or administer.
    Catalyst breaks this out into separate files. Those files happen to
    be the various Models and Controllers. I don't understand what you
    are trying to gain that isn't already there.

    Or, write a base set of rules for display by the user's language.
    What's "edit" in Spanish anyway?]
    Localization is the job of the View.
    One beauty of this scheme is that you could probably work out a way
    to re-load the rules on the fly, allowing for lightning-quick
    development and testing.
    http://search.cpan.org/~msergeant/Apache-Reload-0.07/Reload.pm

    Another is that you could go many miles further on standard CRUD
    views with a good base of default rules. Default rules would come
    up with good display names for columns by changing under-bars to
    spaces and capitalizing words. On top of that you could single out
    exceptions by writing rules that would override the default, for
    instance, acronyms would need to have rules like, "if column name
    is nasa, then display name is 'NASA'", note that a rule like this
    is good for any page or situation. Some rules will start "if user
    is sales" but they don't all have to. Therein lay the power of rule-
    based rapid application development, a rule has the scope you give
    it. It can affect the entire application or just a single component
    in a very particular situation.
    1) Feel free to contribute the Catalyst::Model and
    Catalyst::Controller classes to do these things; I would probably use
    them.

    2) If you write them, please do not do substitutions such as nasa ->
    NASA automatically. If my DB schema happens to have been written in
    Urdu, where 'nasa' means "number of users" (*), I do not want the
    column presentation mangled.

    (*) I'm making this up; I don't speak Urdu.
    The adept may recognize that I miss my rule file from WebObjects,
    but the truth is, he who can deliver this functionality in a simple
    way with Perl would gain fame, fortune and honor before all.
    You go, then! Let me know how it works out...personally, I'm pretty
    happy with Catalyst thus far.

    --Dks
  • Justin Tocci at Jun 6, 2005 at 5:23 pm
    Thanks David for replying.

    You are right, my diagram was rough. Thank you for your clarification.
    I am not sure that you are really familiar with the MVC pattern. Ouch.
    The Platonic ideal MVC system has all business logic in the
    Controller,
    all state in the Model, and all presentation is handled by the View.
    I disagree. I think the controller should control program flow in a
    generic way, and that business logic is best factored out of it.
    How much more separated out can the business logic get? Or are you
    saying that it could be stored off in a config file (or DB)
    somewhere?
    This is exactly what I'm saying. Ideally, the controller should go to
    a different component to get the business logic, where all the
    business logic and only the business logic lives. I don't want this
    to get political, so... consider the example below.
    If so, you program needs to interact with those business
    rules somehow, so who's job is it to pull those rules in and
    interpret them?
    The controller.

    Example:

    You have a View component that should act a little differently
    sometimes. For instance, a list page component should have a
    different title depending on which table it is displaying. One way to
    do it would be to have a separate component for each, another might
    be to put logic in the View that picks a different title based on the
    name of the table it is displaying. Another might be to put the logic
    in the controller.

    What I am proposing is to set the business logic off to the side,
    separate it from the controller. This way you have all your business
    logic in one easy to read place. You have no duplicate components,
    and your logic isn't in the view. Most people (I think) would put it
    in the controller, and that means it gets caught up in with the logic
    for program flow, making the code harder to read, write and maintain.
    So pull it out. Program flow to the left, business logic to the
    right. You start with a default set of rules with low priorities and
    override them with your rules by giving them higher priorities. When
    your rules don't override the default, the default rule wins and is
    used.

    Example default rules:
    10 column name should substitute under bars with spaces
    10 column name should be capitalized
    10 IF column type is 'date' THEN display format is 'mm-dd-yy'

    Custom rules:
    100 IF column name is 'nasa' THEN display 'NASA'
    100 IF column name is 'describes' THEN display 'Description'
    100 IF column type is date and user type is government THEN display
    format is 'yyyy-mmm-dd'

    Result:
    column name 'easy_money' displays as 'Easy Money'
    column name 'nasa' displays 'NASA'
    column name 'describes' displays 'Description'
    user type is 'commercial' and column type is date, format is 'mm-dd-yy'
    user type is 'government' and column type is date, format is 'yyyy-
    mmm-dd'

    Advantages:
    Rules promote re-use of your basic components by allowing easier on-
    the-fly customization.
    The scope side of the rules is very powerful. It allows you to write
    rules that affect your whole app, a very particular situation, or
    anything in between.
    Format is clear. Easy to read, write and maintain.
    Rule file could be re-used in applications with completely different
    program flow, in effect, it becomes a re-usable component for that
    organization or company.
    Catalyst breaks this out into separate files. Those files happen to
    be the various Models and Controllers. I don't understand what you
    are trying to gain that isn't already there.
    I'm a beginner and it shows.
    Sorry, at this point I'm looking for confirmation that Catalyst is
    the right tool to attempt this with, and perhaps tips on how. You are
    the second person to respond like this and that gives me confidence
    I'm in the right place. Thank you.
    Localization is the job of the View.
    Sorry, you are right of course. I was imagining a particular view
    file that has the proper localization might be chosen by the business
    logic if the localization preference was stored in the database. It
    is admittedly a contrived example, but at the time I was trying to
    contrive examples.
    One beauty of this scheme is that you could probably work out a way
    to re-load the rules on the fly, allowing for lightning-quick
    development and testing.
    http://search.cpan.org/~msergeant/Apache-Reload-0.07/Reload.pm
    Understood.
    1) Feel free to contribute the Catalyst::Model and
    Catalyst::Controller classes to do these things; I would probably use
    them.
    Cool. I'll take that as a compliment.
    You go, then! Let me know how it works out...personally, I'm pretty
    happy with Catalyst thus far.

    --Dks
    I hope you feel I was responsive to your questions. I'm going to try
    to implement, but I'm not sure how yet. I also am very happy with
    Catalyst, it is very professionally done in my opinion--it certainly
    doesn't need my help. Thank you for writing.

    justin
  • Sebastian Riedel at Jun 6, 2005 at 5:55 pm

    Am 06.06.2005 um 17:25 schrieb Justin Tocci:
    This is exactly what I'm saying. Ideally, the controller should go
    to a different component to get the business logic, where all the
    business logic and only the business logic lives. I don't want this
    to get political, so... consider the example below.
    What exactly do you mean with "business logic"?

    Actually it looks like you want to build a Maypole like application
    based on Catalyst,
    which provides a big n messy config file for "business logic",
    something we all know (and hate) from the Java world... do i
    misunderstand?

    --
    sebastian
  • David Storrs at Jun 6, 2005 at 6:15 pm

    On Jun 6, 2005, at 11:25 AM, Justin Tocci wrote:

    Thanks David for replying.
    Not a problem. You have an interesting concept.
    The Platonic ideal MVC system has all business logic in the
    Controller,
    all state in the Model, and all presentation is handled by the View.
    I disagree. I think the controller should control program flow in a
    generic way, and that business logic is best factored out of it.
    Well, two thoughts here. First, I was talking about how the MVC
    pattern is usually presented in the literature. I believe you are
    talking about how you think the MVC pattern /should/ work.

    Second...your idea is interesting, and very powerful if done right,
    but I'm cautious about it. I think it might end up being a silver
    bullet that hits you in the foot. See below for why.

    How much more separated out can the business logic get? Or are you
    saying that it could be stored off in a config file (or DB)
    somewhere?
    This is exactly what I'm saying. Ideally, the controller should go
    to a different component to get the business logic, where all the
    business logic and only the business logic lives. I don't want this
    to get political, so... consider the example below.
    Basically, you are talking about reducing the Controller to a pure
    dispatch role--it accepts events from the external world and forwards
    them to the business logic component.

    Although this is good in theory, what it really amounts to is another
    layer of indirection with associated overhead. The code to handle
    dispatch is pretty minor--especially in Catalyst, where it pretty
    much just consists of putting an attribute on the subroutine that
    implements the business logic. I don't see what win you are looking
    to get by this separation.

    Well, maybe I do...you are saying you want to have the logic in the
    DB, and have the controller fetch it out as needed. This is often
    called SCID programming (Source Code In Database), and it has some
    powerful potential, although I personally have never seen a good
    implementation of it.

    In this case, the problem is that either (A) the Controller will need
    to have enough knowledge of the business logic to know what to fetch
    (at which point you might as well have just put the business logic
    directly in the Controller and saved a DB access), or (B) the
    Controller must simply dispatch the request to the business logic
    component and say "here, I got this...figure out what to do with
    it." Option B is exactly what Catalyst does now, so this just adds a
    redundant dispatch cycle.

    Example:

    You have a View component that should act a little differently
    sometimes. For instance, a list page component should have a
    different title depending on which table it is displaying. One way
    to do it would be to have a separate component for each, another
    might be to put logic in the View that picks a different title
    based on the name of the table it is displaying. Another might be
    to put the logic in the controller.
    Another would be to use a template (c.f. Template Toolkit,
    HTML::Mason, etc), where the title is filled in from a variable.
    This is the way Catalyst currently does it. I think this is exactly
    what you're looking for--the "business logic" (i.e., what title to
    use) is in the template file on disk, not in the View (or Controller,
    or Model) class.

    What I am proposing is to set the business logic off to the side,
    separate it from the controller. This way you have all your
    business logic in one easy to read place. You have no duplicate
    components, and your logic isn't in the view. Most people (I think)
    would put it in the controller, and that means it gets caught up in
    with the logic for program flow, making the code harder to read,
    write and maintain. So pull it out. Program flow to the left,
    business logic to the right. You start with a default set of rules
    with low priorities and override them with your rules by giving
    them higher priorities. When your rules don't override the default,
    the default rule wins and is used.

    Example default rules:
    10 column name should substitute under bars with spaces
    10 column name should be capitalized
    10 IF column type is 'date' THEN display format is 'mm-dd-yy'

    Custom rules:
    100 IF column name is 'nasa' THEN display 'NASA'
    100 IF column name is 'describes' THEN display 'Description'
    100 IF column type is date and user type is government THEN display
    format is 'yyyy-mmm-dd'

    Result:
    column name 'easy_money' displays as 'Easy Money'
    column name 'nasa' displays 'NASA'
    column name 'describes' displays 'Description'
    user type is 'commercial' and column type is date, format is 'mm-dd-
    yy'
    user type is 'government' and column type is date, format is 'yyyy-
    mmm-dd'

    Advantages:
    Rules promote re-use of your basic components by allowing easier on-
    the-fly customization.
    The scope side of the rules is very powerful. It allows you to
    write rules that affect your whole app, a very particular
    situation, or anything in between.
    Format is clear. Easy to read, write and maintain.
    Rule file could be re-used in applications with completely
    different program flow, in effect, it becomes a re-usable component
    for that organization or company.
    This is called (logically enough) "rules-based programming" and there
    are entire languages written around it...e.g. Prolog.

    Based on my limited experience of it, RBP is really, really hard.

    The problem is that there is no clear control flow; the easiest way
    to think of it (for me) is from a quantum mechanical standpoint:
    every rule represents a probability of some particular outcome. The
    rules engine takes all the rules, superimposes them into a unified
    waveform, and then collapses that waveform into a single outcome.
    How exactly you got that particular outcome is hard to track. Which
    rules fired? In what order? For example, in your list above, you
    have 'easy_money' display as 'Easy Money' because the 'substitute
    underscore' and 'capitalize name' rules fired in that order. If they
    had fired in the opposite order, then 'easy_money' would display as
    'Easy money'. How do you ensure that these rules fire in the correct
    order? Once you've done that, how do you insert a new rule into the
    chain at the correct point? All of these questions are answerable,
    but they are not trivial.

    If you want to get a taste of RBP, you might try playing around with
    the CLIPS expert system a bit... http://www.pst.com/clpbro.htm
    Do a couple toy projects in it and then see if you still have the
    same enthusiasm for RBP. If so, then by all means go ahead and write
    the necessary Engines/Models/Controllers for Catalyst...I think it
    would be a useful addition to the Catalyst menagerie. But make sure
    you know what you're getting into, first.
    Sorry, at this point I'm looking for confirmation that Catalyst is
    the right tool to attempt this with, and perhaps tips on how. You
    are the second person to respond like this and that gives me
    confidence I'm in the right place. Thank you.
    You're welcome...glad to be of assisstance. I hope some of this
    stuff is useful to you.

    --Dks
  • Justin Tocci at Jun 6, 2005 at 6:56 pm

    Basically, you are talking about reducing the Controller to a pure
    dispatch role--it accepts events from the external world and
    forwards them to the business logic component.

    Although this is good in theory, what it really amounts to is
    another layer of indirection with associated overhead. The code to
    handle dispatch is pretty minor--especially in Catalyst, where it
    pretty much just consists of putting an attribute on the subroutine
    that implements the business logic. I don't see what win you are
    looking to get by this separation.

    Well, maybe I do...you are saying you want to have the logic in the
    DB, and have the controller fetch it out as needed. This is often
    called SCID programming (Source Code In Database), and it has some
    powerful potential, although I personally have never seen a good
    implementation of it.
    Actually I'd rather see the rules in a simple file than in the database.
    In this case, the problem is that either (A) the Controller will
    need to have enough knowledge of the business logic to know what to
    fetch (at which point you might as well have just put the business
    logic directly in the Controller and saved a DB access), or (B) the
    Controller must simply dispatch the request to the business logic
    component and say "here, I got this...figure out what to do with
    it." Option B is exactly what Catalyst does now, so this just adds
    a redundant dispatch cycle.
    (B) is definitely what I'm looking for. The controller fetches an
    object that has some variable built into it, it checks the rule file
    for how to evaluate it, fills it in, then sends the component off.
    Example:

    You have a View component that should act a little differently
    sometimes. For instance, a list page component should have a
    different title depending on which table it is displaying. One way
    to do it would be to have a separate component for each, another
    might be to put logic in the View that picks a different title
    based on the name of the table it is displaying. Another might be
    to put the logic in the controller.
    Another would be to use a template (c.f. Template Toolkit,
    HTML::Mason, etc), where the title is filled in from a variable.
    This is the way Catalyst currently does it. I think this is
    exactly what you're looking for--the "business logic" (i.e., what
    title to use) is in the template file on disk, not in the View (or
    Controller, or Model) class.
    I'm trying to factor that out of the template to make the template a
    strictly generic reusable object. I'm trying to imagine one place
    where all the logic of how to determine the values for those
    variables would be stored, and if necessary, manually overridden.
    This is called (logically enough) "rules-based programming" and
    there are entire languages written around it...e.g. Prolog.

    Based on my limited experience of it, RBP is really, really hard.

    The problem is that there is no clear control flow; the easiest way
    to think of it (for me) is from a quantum mechanical standpoint:
    every rule represents a probability of some particular outcome.
    The rules engine takes all the rules, superimposes them into a
    unified waveform, and then collapses that waveform into a single
    outcome.
    You're a good writer you know that? Many couldn't have explained such
    a concept so succinctly.
    How exactly you got that particular outcome is hard to track.
    Which rules fired? In what order? For example, in your list
    above, you have 'easy_money' display as 'Easy Money' because the
    'substitute underscore' and 'capitalize name' rules fired in that
    order. If they had fired in the opposite order, then 'easy_money'
    would display as 'Easy money'. How do you ensure that these rules
    fire in the correct order?
    Sorry, you are right. The capitalization rule should have had a
    higher priority than the under bar rule:

    Example default rules:
    10 column name should substitute under bars with spaces
    10 IF column type is 'date' THEN display format is 'mm-dd-yy'
    15 column name should be capitalized

    Custom rules:
    100 IF column name is 'nasa' THEN display 'NASA'
    100 IF column name is 'describes' THEN display 'Description'
    100 IF column type is date and user type is government THEN display
    format is 'yyyy-mmm-dd'
    Once you've done that, how do you insert a new rule into the chain
    at the correct point? All of these questions are answerable, but
    they are not trivial.
    It seems trivial to put a priority level on the rules, search from
    high to low, and when the first match is made that answers the
    questions needing answering, you're done searching; but I am looking
    at it through different eyes.
    If you want to get a taste of RBP, you might try playing around
    with the CLIPS expert system a bit... http://www.pst.com/clpbro.htm
    Do a couple toy projects in it and then see if you still have the
    same enthusiasm for RBP. If so, then by all means go ahead and
    write the necessary Engines/Models/Controllers for Catalyst...I
    think it would be a useful addition to the Catalyst menagerie. But
    make sure you know what you're getting into, first.
    Will do. Thank you again.


    justin

    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: http://lists.rawmode.org/pipermail/catalyst/attachments/20050606/1ba74c3c/attachment.html
  • David Storrs at Jun 6, 2005 at 7:42 pm

    On Jun 6, 2005, at 12:57 PM, Justin Tocci wrote:
    Actually I'd rather see the rules in a simple file than in the
    database.
    Out of curiosity, why? It is easier to attach metadata to the rules
    in a DB.

    In this case, the problem is that either (A) the Controller will
    need to have enough knowledge of the business logic to know what
    to fetch (at which point you might as well have just put the
    business logic directly in the Controller and saved a DB access),
    or (B) the Controller must simply dispatch the request to the
    business logic component and say "here, I got this...figure out
    what to do with it." Option B is exactly what Catalyst does now,
    so this just adds a redundant dispatch cycle.
    (B) is definitely what I'm looking for. The controller fetches an
    object that has some variable built into it, it checks the rule
    file for how to evaluate it, fills it in, then sends the component
    off.
    Example:

    You have a View component that should act a little differently
    sometimes. For instance, a list page component should have a
    different title depending on which table it is displaying. One
    way to do it would be to have a separate component for each,
    another might be to put logic in the View that picks a different
    title based on the name of the table it is displaying. Another
    might be to put the logic in the controller.
    Another would be to use a template (c.f. Template Toolkit,
    HTML::Mason, etc), where the title is filled in from a variable.
    This is the way Catalyst currently does it. I think this is
    exactly what you're looking for--the "business logic" (i.e., what
    title to use) is in the template file on disk, not in the View (or
    Controller, or Model) class.
    I'm trying to factor that out of the template to make the template
    a strictly generic reusable object. I'm trying to imagine one place
    where all the logic of how to determine the values for those
    variables would be stored, and if necessary, manually overridden.
    Ok, two points: 1) 'strictly generic reusable objects' are useless.
    Only when something acquires a certain degree of specificity does it
    become useful. I'm not being sarcastic here...think about it. You
    can't have a 'strictly generic' document that is useful. Simply by
    putting words on the page, you give it some sort of specificity (is
    it a report? a novel? a play?), and that specificity is what makes it
    useful. The trick is deciding what your universe of discourse is for
    this object and then making it as reusable as possible within that
    universe.

    2) I think you should review the Template Toolkit docs (http://
    www.template-toolkit.org). The difference between TT and what you
    are looking for seems to be that, instead of having the templating
    engine know how to fill in variables and evaluate code, you want that
    knowledge to be in a separate file.

    Right now, you can do something like this in TT:

    [% title %]

    And that will be replaced with the contents of the 'title' variable.
    It sounds like you are saying that you don't want this kind of
    directive in the template...that you would rather the template had
    some actual text there which would be magically replaced by the
    business rules. If this is true, how do the business rules know
    where the title begins and ends?

    TT can also do this (assuming the EVAL_PERL option is set on your
    installation of TT):

    [% PERL %]
    print $context->include('myfile');
    [% END %]

    It sounds like you are saying that you want to extract this code from
    the template and put it in a business rules file. In that case, how
    do the business rules know where in the template to insert 'myfile'?
    There needs to be some sort of marker there...which is exactly the
    point of the templating directive.



    Also, how do you see your rendering system being structured? Right
    now, the sequence goes like this:

    - Apache (or other web server) receives request, passes it to
    Catalyst
    - Catalyst calls the relevant action, which happens to reside in
    a View class, passing it certain context
    - the action picks which template to use
    - Catalyst renders that template, filling in appropriate values
    from the context

    Note that the only code you have to write here is the action.
    Everything else is built into Catalyst.


    If I understand what you're saying, you want it to go like this:

    - Apache (or other web server) receives request, passes it to
    Catalyst
    - Catalyst calls the relevant action, which happens to reside in
    a Controller class, passing it certain context
    - the Controller loads certain business rules (from cache or
    from disk)
    - the Controller selects which View should be used
    - the Controller passes the request to the View, along with
    context and business rules
    - the View chooses the template
    - the View populates the template based on the business rules
    (or would this still be done by Catalyst?)
    - Catalyst renders that template

    Is this right?

    This is called (logically enough) "rules-based programming" and
    there are entire languages written around it...e.g. Prolog.

    Based on my limited experience of it, RBP is really, really hard.

    The problem is that there is no clear control flow; the easiest
    way to think of it (for me) is from a quantum mechanical
    standpoint: every rule represents a probability of some
    particular outcome. The rules engine takes all the rules,
    superimposes them into a unified waveform, and then collapses that
    waveform into a single outcome.
    You're a good writer you know that? Many couldn't have explained
    such a concept so succinctly.
    Thanks. I didn't go to college as an English major for nothing, you
    know--I payed thousands and thousands of dollars!

    How exactly you got that particular outcome is hard to track.
    Which rules fired? In what order? For example, in your list
    above, you have 'easy_money' display as 'Easy Money' because the
    'substitute underscore' and 'capitalize name' rules fired in that
    order. If they had fired in the opposite order, then 'easy_money'
    would display as 'Easy money'. How do you ensure that these rules
    fire in the correct order?
    Sorry, you are right. The capitalization rule should have had a
    higher priority than the under bar rule:

    Example default rules:
    10 column name should substitute under bars with spaces
    10 IF column type is 'date' THEN display format is 'mm-dd-yy'
    15 column name should be capitalized
    And there you see the prime problem with RBP: getting the priorities
    right. This was a tiny example...try to imagine what it's like in a
    system with thousands or tens of thousands of rules. My last two
    corporate jobs involved engines that did RBP (one was for natural
    language processing on classified ads, the other was for financial
    software). Both were nightmares.

    If you want to get a taste of RBP, you might try playing around
    with the CLIPS expert system a bit... http://www.pst.com/clpbro.htm
    Will do. Thank you again.

    Just to be fair...I'll warn you that I worked with CLIPS in college
    (long, long ago) and it drove me insane. You Have Been Warned. :>

    --Dks
  • Justin Tocci at Jun 6, 2005 at 8:08 pm

    Actually I'd rather see the rules in a simple file than in the
    database.
    Out of curiosity, why? It is easier to attach metadata to the
    rules in a DB.
    Seemed easier to me since its what I'm used to. You are right though.
    It may in fact be easier to put them in the database and query for
    what you're looking for.
    Ok, two points: 1) 'strictly generic reusable objects' are
    useless. Only when something acquires a certain degree of
    specificity does it become useful. I'm not being sarcastic
    here...think about it. You can't have a 'strictly generic'
    document that is useful. Simply by putting words on the page, you
    give it some sort of specificity (is it a report? a novel? a
    play?), and that specificity is what makes it useful. The trick is
    deciding what your universe of discourse is for this object and
    then making it as reusable as possible within that universe.

    2) I think you should review the Template Toolkit docs (http://
    www.template-toolkit.org). The difference between TT and what you
    are looking for seems to be that, instead of having the templating
    engine know how to fill in variables and evaluate code, you want
    that knowledge to be in a separate file.

    Right now, you can do something like this in TT:

    [% title %]

    And that will be replaced with the contents of the 'title'
    variable. It sounds like you are saying that you don't want this
    kind of directive in the template...that you would rather the
    template had some actual text there which would be magically
    replaced by the business rules. If this is true, how do the
    business rules know where the title begins and ends?
    No no, I like the [% title %]; I want the [% title %]. I just want
    the logic for how to replace [% title %] with a value to be in a
    place with all the other similar logic.
    Also, how do you see your rendering system being structured? Right
    now, the sequence goes like this:

    - Apache (or other web server) receives request, passes it to
    Catalyst
    - Catalyst calls the relevant action, which happens to reside
    in a View class, passing it certain context
    - the action picks which template to use
    - Catalyst renders that template, filling in appropriate values
    from the context

    Note that the only code you have to write here is the action.
    Everything else is built into Catalyst.


    If I understand what you're saying, you want it to go like this:

    - Apache (or other web server) receives request, passes it to
    Catalyst
    - Catalyst calls the relevant action, which happens to reside
    in a Controller class, passing it certain context
    - the Controller loads certain business rules (from cache or
    from disk)
    - the Controller selects which View should be used
    - the Controller passes the request to the View, along with
    context and business rules
    - the View chooses the template
    - the View populates the template based on the business rules
    (or would this still be done by Catalyst?)
    - Catalyst renders that template

    Is this right?
    I am very sorry. As far as how it should go, its over my head. I was
    hoping someone would say: "its already there, just do this... "
    Thanks. I didn't go to college as an English major for nothing,
    you know--I payed thousands and thousands of dollars! :-)
    And there you see the prime problem with RBP: getting the
    priorities right. This was a tiny example...try to imagine what
    it's like in a system with thousands or tens of thousands of
    rules. My last two corporate jobs involved engines that did RBP
    (one was for natural language processing on classified ads, the
    other was for financial software). Both were nightmares.
    I see, well, one man's nightmare is another man's dream!
    Just to be fair...I'll warn you that I worked with CLIPS in college
    (long, long ago) and it drove me insane. You Have Been Warned. :>
    I'll keep a safe distance. Thank you. ;-)

    justin
  • Perrin Harkins at Jun 6, 2005 at 7:11 pm

    On Mon, 2005-06-06 at 12:15 -0400, David Storrs wrote:
    I disagree. I think the controller should control program flow in a
    generic way, and that business logic is best factored out of it.
    Well, two thoughts here. First, I was talking about how the MVC
    pattern is usually presented in the literature. I believe you are
    talking about how you think the MVC pattern /should/ work.
    Maybe we're just reading different literature, but I've usually seen MVC
    described closer to the way he's talking about it, i.e. the controller
    is a totally generic mechanism for turning mouse clicks into method
    calls, and contains no "domain" knowledge at all. The idea that the
    model is just a set of database access objects and that flow control
    goes in the controller is a relatively recent change stemming from the
    use in web apps.

    - Perrin
  • Justin Tocci at Jun 6, 2005 at 7:39 pm
    I'm not sure what you're saying here.

    Closer to me or David?
    Is '"domain" knowledge' referring to business logic or flow control
    or something else?

    I agree that flow control is necessitated by the web in a way that
    was unnecessary for desktop apps. However, in a simple desktop app,
    flow control is often left up to the user. They get a menu and can go
    where they wish. But more complex apps have always said they need to
    log in first, etc... Hmm, ok, this would be business logic more than
    flow control too I think.

    Ah-hem. I agree that flow control is necessitated by the web in a way
    that was unnecessary for desktop apps. ;-)

    By the way, what was the Model before it was "just a set of database
    access objects"?

    justin


    On Jun 6, 2005, at 12:13 PM, Perrin Harkins wrote:
    On Mon, 2005-06-06 at 12:15 -0400, David Storrs wrote:

    I disagree. I think the controller should control program flow in a
    generic way, and that business logic is best factored out of it.
    Well, two thoughts here. First, I was talking about how the MVC
    pattern is usually presented in the literature. I believe you are
    talking about how you think the MVC pattern /should/ work.
    Maybe we're just reading different literature, but I've usually
    seen MVC
    described closer to the way he's talking about it, i.e. the controller
    is a totally generic mechanism for turning mouse clicks into method
    calls, and contains no "domain" knowledge at all. The idea that the
    model is just a set of database access objects and that flow control
    goes in the controller is a relatively recent change stemming from the
    use in web apps.

    - Perrin

  • David Storrs at Jun 6, 2005 at 7:46 pm

    On Jun 6, 2005, at 1:40 PM, Justin Tocci wrote:

    I'm not sure what you're saying here.

    Closer to me or David?
    Closer to you.

    Perrin: Well, it's possible that I've just misunderstood what I've
    read. Or that I'm only reading the recent, changed versions. If so,
    apologies to all concerned for muddying the waters.

    Is '"domain" knowledge' referring to business logic or flow control
    or something else?
    Business logic.


    --Dks
  • Perrin Harkins at Jun 6, 2005 at 7:46 pm

    On Mon, 2005-06-06 at 12:40 -0500, Justin Tocci wrote:
    Closer to me or David? You.
    Is '"domain" knowledge' referring to business logic or flow control
    or something else?
    It's "business logic." OO modeling literature often refers to "the
    problem domain" or "domain objects" to mean something that is specific
    to the problem you are working on rather than a totally generic
    computing problem.
    I agree that flow control is necessitated by the web in a way that
    was unnecessary for desktop apps. However, in a simple desktop app,
    flow control is often left up to the user. They get a menu and can go
    where they wish. But more complex apps have always said they need to
    log in first, etc... Hmm, ok, this would be business logic more than
    flow control too I think.
    There's hardly any useful distinction between the two in my opinion.
    By the way, what was the Model before it was "just a set of database
    access objects"?
    It was the sum total of all your data and all the things it can do.
    Most of the stuff that people write in their controller methods now
    would have been part of the model.

    - Perrin
  • Dominique Quatravaux at Jun 9, 2005 at 12:35 pm

    Perrin Harkins wrote:

    The idea that the model is just a set of database access objects
    and that flow control goes in the controller is a relatively recent
    change stemming from the use in web apps.
    I have come to think that this is a somewhat undesirable artifact of
    the way the Web influences said flow control. In a desktop app without
    modal dialogs (such as Smalltalk GUIs from which the MVC paradigm
    originated), it is not possible to tell what the user will click next
    and thus the controller has to be maximally flexible. Therefore all
    flow control has to reside elsewhere, typically the model (which
    throws exceptions upon forbidden state changes, which in turn will
    result in error dialog boxes popping up).

    The Web environment has quite the reverse problem: the developer
    typically tries to foresee the sequence of clicks the user will have
    to go through, and will block forbidden actions through surface tests
    (form validation) or by simply not showing the appropriate buttons in
    the view (which typically has adverse consequences in terms of
    security, since a quick wget can easily circumvent that). Hence some
    flow control slowly creeps into the controller (for a secure app) or
    even the view (for an insecure one).

    I am of the opinion that the first option is the best one, if the
    above two are the only choices: not only because it enforces security,
    but also because preventing nonsensical updates of the model is also
    profitable to non-Web parts of the app such as crontabs, so it is best
    done in the model (or even deeper, directly within the database using
    SQL triggers or such). Also of interest are serializable continuations
    (http://seaside.st/) which basically allow GUI-like programming in a
    Web environment, but unfortunately they are a very difficult trick to
    pull in Perl.

    Now I am under the impression that the "business logic" idea being
    discussed in this thread (which IMHO is somehow related to "widgets",
    http://www.officevision.com/pub/Widget/) solves its own set of
    problems, such as automatically telling the view that that particular
    button or input field should be greyed out because its action would be
    refused anyway. I'm not yet sure how it should integrate properly with
    the rest of MVC though, so I find the thread of great interest. (And
    I'm awaiting Perrin's talk with impatience!)

    - --
    Dominique QUATRAVAUX Ing?nieur senior
    01 44 42 00 08 IDEALX
  • David Storrs at Jun 9, 2005 at 3:02 pm

    On Jun 9, 2005, at 6:37 AM, Dominique Quatravaux wrote:
    Now I am under the impression that the "business logic" idea being
    discussed in this thread (which IMHO is somehow related to "widgets",
    I generally agree with what you said, but I think this particular
    point is off base. Business logic is just the set of rules that
    describe what operations should be carried out on the data, and how
    the state should change. "When selling to a customer in Europe, add
    VAT tax to the price" is a business rule. These things have nothing
    to do with widgets...there may be widgets onscreen which are involved
    in gathering information for, or expressing the results of, or
    triggering, business rules, but those widgets are not part of the
    business rule per se.

    Other than that, though--you've got good points.

    --Dks
  • Sebastian Riedel at Jun 9, 2005 at 4:06 pm

    Am 09.06.2005 um 12:37 schrieb Dominique Quatravaux:
    I am of the opinion that the first option is the best one, if the
    above two are the only choices: not only because it enforces security,
    but also because preventing nonsensical updates of the model is also
    profitable to non-Web parts of the app such as crontabs, so it is best
    done in the model (or even deeper, directly within the database using
    SQL triggers or such). Also of interest are serializable continuations
    (http://seaside.st/) which basically allow GUI-like programming in a
    Web environment, but unfortunately they are a very difficult trick to
    pull in Perl.
    Continuations may be nice for traditional multi page form wizards,
    but these days we have Ajax for stateful webapps!

    --
    sebastian
  • Justin Tocci at Jun 10, 2005 at 1:54 am
    'Business Logic' is a more ambiguous phrase than I thought. After
    some thought, I think I would have been better off using the term
    'business rules', but not by much.

    David Storrs had this to say to Dominique:
    Business logic is just the set of rules that
    describe what operations should be carried out on the data, and how
    the state should change. "When selling to a customer in Europe, add
    VAT tax to the price" is a business rule. These things have nothing
    to do with widgets...there may be widgets onscreen which are involved
    in gathering information for, or expressing the results of, or
    triggering, business rules, but those widgets are not part of the
    business rule per se.
    I agree with David that the business rules are not the widgets and
    vice versa, but I think they are related. To me, they are a
    substitute for methods. Sometimes the method is overridden and a
    value is assigned directly, but its still a method. Sometimes the
    method will change a data format, sometimes it could modify your
    view, like prettying up column names. As David pointed out, it might
    figure your tax. I think rules are best used to configure your
    components. Methods that work on your data I would put in the model
    and I'm not referring to them at all.

    Figuring your tax might work as a method in your model, but the
    information for which tax to apply is likely to be in your session,
    whereas a method in the model would be more appropriate when the
    input has to be found on disk. I reason, figure the tax when the
    session is in hand, then send out to view or commit to disk.
    Additionally, to put a method in your model to change a data format
    for some customers and not others could be wasteful. It doesn't
    concern the database, and might incur a performance hit due to a
    change in data type, higher in the model would be better, but it
    would also need logic to determine when to show one format, and when
    to show the other. This is again information that should be in the
    session, hence it would make more sense to decide when your session
    is available.

    A widget may be reusable in the sense that more than one customer can
    use it, but this should be taken for granted. Reusability should be
    more about using the same widget in more situations. Rules allow you
    to configure widgets so that they can fit more situations. In David's
    example above, three rules about figuring tax would allow you to
    reuse your tax page for three tax situations, and you wouldn't have
    to change the code for the page to add a fourth. That's my definition
    of a reusable widget.

    I would argue that without rules, you can't have reusable widget at
    all. If you have an object, say a page view, hard coded to display a
    list of items, it has to be re-written to display a different list.
    That isn't a reusable widget. Now if you can tell it what category of
    items to display when you call it, then its reusable, and the
    configuration information you sent constitutes a rule to me.

    Now, I advocate putting all such rules in one place. Separately, I
    advocate giving rules a 'scope' so that you can assign properties to
    more that one widget at a time. I also like the idea of having a
    priority level so that you can have a base of default rules and build
    on them for more and more specific situations. But, a rule, to me, is
    something every OO program uses every time it configures an object.
    I'm not talking about instantiation, but configuration, and they
    don't belong in the model for practical reasons.

    justin tocci
    Fort Worth, Texas
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: http://lists.rawmode.org/pipermail/catalyst/attachments/20050609/2eb29359/attachment.html
  • Tony Bowden at Jun 9, 2005 at 6:00 pm

    On 06/06/05, Perrin Harkins wrote:
    The idea that the model is just a set of database access objects and that flow control
    goes in the controller is a relatively recent change stemming from the use in web apps.
    I think some of this also comes from the "dilution" of OO towards
    table based programming in lots of web apps. The idea of a
    straight-forward mapping of a database row to an object is anathema to
    most OO purists.

    Tony
  • Zbyszek Lukasiak at Jun 15, 2005 at 10:57 am
    I seems that in Web apps MVC is more defined by available tools than by
    some theory:

    Model - all code that you sometimes might need to call outside of the
    web environment like in crontabs.

    View - everything you can get from HTML templates

    Controller - all the rest

    -- Zbyszek Lukasiak

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupcatalyst @
categoriescatalyst, perl
postedJun 2, '05 at 5:47p
activeJun 15, '05 at 10:57a
posts21
users7
websitecatalystframework.org
irc#catalyst

People

Translate

site design / logo © 2022 Grokbase