Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Catalyst: Users

ways to do stuff and why

 

 

Catalyst users RSS feed   Index | Next | Previous | View Threaded


danielmcbrearty at gmail

Aug 18, 2006, 2:47 AM

Post #1 of 24 (4427 views)
Permalink
ways to do stuff and why

if you need to add some block of functionality to your project, how
many ways are there to do it?

1. Add a model. For any data source, maybe with some "intelligence"
hidden in it.
2. Add a controller. To add specific functions to one project.
3. Add a controller base class. To add functions that are reusable
across projects.
4. Write a plugin ... erm , I forgot ;-)

what did I miss out? (I didn't add the View, as far as I can see you
pretty much choose your templating system and stick with it ... but
quite likely I missed something there ...)

A bit of POD summarising the catalogue of techniques that is available
and guidelines as to how to select might be very useful. Hell, I might
even try to write it if I get enough useful info from this thread ...

cheers

D

--
Daniel McBrearty
email : danielmcbrearty at gmail.com
www.engoi.com : the multi - language vocab trainer
BTW : 0873928131

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


jjn1056 at yahoo

Aug 18, 2006, 9:21 AM

Post #2 of 24 (4364 views)
Permalink
Re: ways to do stuff and why [In reply to]

You may want to review the thread, "Plugins vs. Base Controllers" to see what some of the lead architects have to say on the issue at least regarding 2/3 and 4. I think choosing between 2/3 is really a matter of what can be reused usefully and what is overkill design. For 1 I am not sure but I only put a little logic in the models for stuff directly related to the model, like to encapsulate very frequently used queries. Not sure what other people have to say. Purists I think don't want any logic in the model, from what I gather.

--john

----- Original Message ----
From: Daniel McBrearty <danielmcbrearty [at] gmail>
To: The elegant MVC web framework <catalyst [at] lists>
Sent: Friday, August 18, 2006 5:47:36 PM
Subject: [Catalyst] ways to do stuff and why

if you need to add some block of functionality to your project, how
many ways are there to do it?

1. Add a model. For any data source, maybe with some "intelligence"
hidden in it.
2. Add a controller. To add specific functions to one project.
3. Add a controller base class. To add functions that are reusable
across projects.
4. Write a plugin ... erm , I forgot ;-)

what did I miss out? (I didn't add the View, as far as I can see you
pretty much choose your templating system and stick with it ... but
quite likely I missed something there ...)

A bit of POD summarising the catalogue of techniques that is available
and guidelines as to how to select might be very useful. Hell, I might
even try to write it if I get enough useful info from this thread ...

cheers

D

--
Daniel McBrearty
email : danielmcbrearty at gmail.com
www.engoi.com : the multi - language vocab trainer
BTW : 0873928131

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/




_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


dbix-class at trout

Aug 18, 2006, 9:33 AM

Post #3 of 24 (4343 views)
Permalink
Re: ways to do stuff and why [In reply to]

John Napiorkowski wrote:
> You may want to review the thread, "Plugins vs. Base Controllers" to see what some of the lead architects have to say on the issue at least regarding 2/3 and 4. I think choosing between 2/3 is really a matter of what can be reused usefully and what is overkill design. For 1 I am not sure but I only put a little logic in the models for stuff directly related to the model, like to encapsulate very frequently used queries. Not sure what other people have to say. Purists I think don't want any logic in the model, from what I gather.

Eeeeek, not at all. The model should encapsulate *all* business logic and
similar - it should be a model of the domain with which the app interacts. The
Controller should be as thin a layer as possible whose sole purpose is to
arbitrate between the model's view of reality and the user interface (i.e. the
view)

--
Matt S Trout Offering custom development, consultancy and support
Technical Director contracts for Catalyst, DBIx::Class and BAST. Contact
Shadowcat Systems Ltd. mst (at) shadowcatsystems.co.uk for more information

+ Help us build a better perl ORM: http://dbix-class.shadowcatsystems.co.uk/ +

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


leonard.a.jaffe at jpmchase

Aug 18, 2006, 10:15 AM

Post #4 of 24 (4355 views)
Permalink
Re: ways to do stuff and why [In reply to]

------------------------------------------------------------------------------
Leonard A. Jaffe (614)213-4283
JP Morgan Chase, DTS Instrumentation Services
leonard.a.jaffe [at] jpmchase




Matt S Trout <dbix-class [at] trout> on 08/18/2006 12:33 PM:
> Eeeeek, not at all. The model should encapsulate *all* business logic
and
> similar - it should be a model of the domain with which the app
interacts. The
> Controller should be as thin a layer as possible whose sole purpose is
to
> arbitrate between the model's view of reality and the user interface
(i.e. the
> view)

I disagree.

In an MVC sense:
The model is the data.
The controller is the business logic.
The controller receives commands from the user interface, and manipulates
the models.
The models are then displayed via views

The model insulates the controller from the data storage/retrieval
mechanism.

The controller should be useable via any interface (command line, gui,
web).

If you want to talk about object composition...

I like for there to be one set of classes that represent the data,
and encapsulate persistence, like (DBIC, CDBI, homegrown, etc).

I like a layer around those, representing the domain objects
(contracts, users, invoices) which implement the manipulation of the
models

Then I like objects that encapsulate the business processes, to manipulate

the domain objects (new invoice, delete user) . I like objects, but
sometimes I just write functions, because object purists end up with
Smalltalk,
and then they tell the 3 object to add itself to another three object, and
at
that point, I'm curled up in the fetal position whimpering "primitives...I
want primitives"

It can all get very messy. I strive for some kind of workable
consistency, without
becoming dogmatic.


Len.


-----------------------------------------
This transmission may contain information that is privileged,
confidential, legally privileged, and/or exempt from disclosure
under applicable law. If you are not the intended recipient, you
are hereby notified that any disclosure, copying, distribution, or
use of the information contained herein (including any reliance
thereon) is STRICTLY PROHIBITED. Although this transmission and
any attachments are believed to be free of any virus or other
defect that might affect any computer system into which it is
received and opened, it is the responsibility of the recipient to
ensure that it is virus free and no responsibility is accepted by
JPMorgan Chase & Co., its subsidiaries and affiliates, as
applicable, for any loss or damage arising in any way from its use.
If you received this transmission in error, please immediately
contact the sender and destroy the material in its entirety,
whether in electronic or hard copy format. Thank you.


brian.kirkbride at deeperbydesign

Aug 18, 2006, 10:57 AM

Post #5 of 24 (4352 views)
Permalink
Re: ways to do stuff and why [In reply to]

leonard.a.jaffe [at] jpmchase wrote:
> Matt S Trout <dbix-class [at] trout> on 08/18/2006 12:33 PM:
> > Eeeeek, not at all. The model should encapsulate *all* business logic
> and
> > similar - it should be a model of the domain with which the app
> interacts. The
> > Controller should be as thin a layer as possible whose sole purpose
> is to
> > arbitrate between the model's view of reality and the user interface
> (i.e. the
> > view)
>
> I disagree.
>
> In an MVC sense:
> The model is the data.
> The controller is the business logic.
> The controller receives commands from the user interface, and
> manipulates the models.
> The models are then displayed via views

This is what I had thought initially, but I have come to see the benefit of
doing it the way Matt describes.

I have Catalyst and non-Catalyst web applications, CRON jobs and command-line
utility scripts for my project. They all need access to the data in the model,
and that is provided by the ORM. That can be accomplished in either your way or
the logic-in-the-model way.

But many of the command-line tools need to do the same thing as a controller in
the Catalyst application. Sometimes the CRON jobs do too. Since the code in
the Catalyst controller is dependent on the Catalyst request life cycle, it's
not in itself reusable. I don't want Catalyst controllers calling the external
scripts either.

At this point, if I want code reuse I have two reasonable choices:

A) Create business logic modules, ie. MyApp::Logic::CreateTrial, etc
B) Write my own business logic methods in MyApp::Schema::Trial->create(...)

Either is valid and from what I gather Java developers like the Logic route. I
chose (B) because I already have the classes and the logic is *usually* just
operating on that class's data model.

I'm very interested in hearing others' thoughts on this, because it really seems
to be a point of contention in MVC/Web programming.

Best,
Brian

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


claco at chrislaco

Aug 18, 2006, 11:23 AM

Post #6 of 24 (4363 views)
Permalink
Re: ways to do stuff and why [In reply to]

Brian Kirkbride wrote:
> leonard.a.jaffe [at] jpmchase wrote:
>> Matt S Trout <dbix-class [at] trout> on 08/18/2006 12:33 PM:
>> > Eeeeek, not at all. The model should encapsulate *all* business logic
>> and
>> > similar - it should be a model of the domain with which the app
>> interacts. The
>> > Controller should be as thin a layer as possible whose sole purpose
>> is to
>> > arbitrate between the model's view of reality and the user interface
>> (i.e. the
>> > view)
>>
>> I disagree.
>>
>> In an MVC sense:
>> The model is the data.
>> The controller is the business logic.
>> The controller receives commands from the user interface, and
>> manipulates the models.
>> The models are then displayed via views
>
> This is what I had thought initially, but I have come to see the benefit of
> doing it the way Matt describes.
>
> I have Catalyst and non-Catalyst web applications, CRON jobs and command-line
> utility scripts for my project. They all need access to the data in the model,
> and that is provided by the ORM. That can be accomplished in either your way or
> the logic-in-the-model way.
>
> But many of the command-line tools need to do the same thing as a controller in
> the Catalyst application. Sometimes the CRON jobs do too. Since the code in
> the Catalyst controller is dependent on the Catalyst request life cycle, it's
> not in itself reusable. I don't want Catalyst controllers calling the external
> scripts either.
>
> At this point, if I want code reuse I have two reasonable choices:
>
> A) Create business logic modules, ie. MyApp::Logic::CreateTrial, etc
> B) Write my own business logic methods in MyApp::Schema::Trial->create(...)
>
> Either is valid and from what I gather Java developers like the Logic route. I
> chose (B) because I already have the classes and the logic is *usually* just
> operating on that class's data model.
>
> I'm very interested in hearing others' thoughts on this, because it really seems
> to be a point of contention in MVC/Web programming.
>
> Best,
> Brian

Right. I agree completely on this. It's a matter of perspective.

Take Handel for instance. In and of itself, it has its own logic and it
has it's own model (storage layer and dbic). Now, when I use Handel
under Catalyst, it is now a model unto it's own. That's the only way to
have good reusability.

Whenever I start a new Catalyst project, my first goal is that all of
the core bits should be able to function outside of the context of a web
app. If I'm creating a store site admin page (Mango anyone?) that can
manager users roles, I first write modules that can manager user roles,
then I use those modules as catalyst Models.

-=Chris
Attachments: signature.asc (0.18 KB)


alex at taskforce-1

Aug 18, 2006, 12:02 PM

Post #7 of 24 (4356 views)
Permalink
Re: ways to do stuff and why [In reply to]

On Friday 18 August 2006 10:57, Brian Kirkbride wrote:
> This is what I had thought initially, but I have come to see the benefit of
> doing it the way Matt describes.

This is the right way of doing it. Another reason for not throwing business
logic into controller is, that sometimes you want to have multiple
controllers supporting variety of interfaces: SOAP,XMLRPC,REST,etc..

This means duplication of business logic across multiple controllers if you
keep business logic in the controller class. Very, very bad. Simple solution,
just keep business logic within the model class, then you can re-use as much
as you want.

> I'm very interested in hearing others' thoughts on this, because it really
> seems to be a point of contention in MVC/Web programming.

Well you just heard mine.

>
> Best,
> Brian
>
> _______________________________________________
> List: Catalyst [at] lists
> Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
> Dev site: http://dev.catalyst.perl.org/

--
Alex Pavlovic - CTO
TF-1 Inc. ( Custom development, consultancy and training )
http://taskforce-1.com

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


leonard.a.jaffe at jpmchase

Aug 18, 2006, 12:10 PM

Post #8 of 24 (4363 views)
Permalink
Re: ways to do stuff and why [In reply to]

Brian Kirkbride <brian.kirkbride [at] deeperbydesign> @ 08/18/2006 01:57
PM:
> leonard.a.jaffe [at] jpmchase wrote:
> > Matt S Trout <dbix-class [at] trout> on 08/18/2006 12:33 PM:
> > > [ Matt's Way ]
> > [ Len's way %]
>
> This is what I had thought initially, but I have come to see the benefit
of
> doing it the way Matt describes.
>
> I have Catalyst and non-Catalyst web applications, CRON jobs and
command-line
> utility scripts for my project. They all need access to the data in the
model,
> and that is provided by the ORM. That can be accomplished in either
your way or
> the logic-in-the-model way.
>
> But many of the command-line tools need to do the same thing as a
controller in
> the Catalyst application. Sometimes the CRON jobs do too. Since the
code in
> the Catalyst controller is dependent on the Catalyst request life cycle,
it's
> not in itself reusable. I don't want Catalyst controllers calling the
external
> scripts either.

Don't code the logic in the catalyst controller. This of the catalyst
controller as
the glue between the web server and Business Logic. let cat handle web
issues:
parsing params & RESTful URIs, calling fillform(), then pass control into
your
business logic, which validates it's input, manipulates domain objects
(which are
composed by ORM objects from the Catalyst Model), and returns some data to
its caller,
which in Cat's case, calls on one or more Views to produce output.

> At this point, if I want code reuse I have two reasonable choices:
>
> A) Create business logic modules, ie. MyApp::Logic::CreateTrial, etc
> B) Write my own business logic methods in
MyApp::Schema::Trial->create(...)
>
> Either is valid and from what I gather Java developers like the Logic
route. I
> chose (B) because I already have the classes and the logic is *usually*
just
> operating on that class's data model.

[Insert snarky Java comment here]

B couples my business logic too tightly with the ORM. ORMs fall out of
fancy.
The whole point of MVC is loose coupling. Method A does not have that
tight coupling.
This is a bit of good advice I've picked up along the way:
Loose coupling of objects. Code to the abstract class (API) not the
implementation.

Sometimes it helps to forget about ORM's for a minute. The hash or array
of data returned
by DBI is still your Model. It you want objects, you have to roll your
own, around the DBI data.
Roll your own around the DBIC data, use object composition, rather than
inheritance. The coupling
is looser, and that makes your code less brittle.

I think some of this debate stems from folks wanting to have an initial
for each object layer, and
no more object layers than initials.

This is similar to the Django team misnaming their Controllers in the
strict MVC sense. When asked if
Django is MVC they say "it's Model/View/'Template". They call their MVC
Controllers "Views", and won't
enter into these kinds of name games. They get away with it largely
because in Django, There's Only
One Way To Do It.

In the end, it's a matter of taste and politics. If we ever meet, we can
argue vociferously over highly
caffienated beverages. I'll buy the first round.

Len.



-----------------------------------------
This transmission may contain information that is privileged,
confidential, legally privileged, and/or exempt from disclosure
under applicable law. If you are not the intended recipient, you
are hereby notified that any disclosure, copying, distribution, or
use of the information contained herein (including any reliance
thereon) is STRICTLY PROHIBITED. Although this transmission and
any attachments are believed to be free of any virus or other
defect that might affect any computer system into which it is
received and opened, it is the responsibility of the recipient to
ensure that it is virus free and no responsibility is accepted by
JPMorgan Chase & Co., its subsidiaries and affiliates, as
applicable, for any loss or damage arising in any way from its use.
If you received this transmission in error, please immediately
contact the sender and destroy the material in its entirety,
whether in electronic or hard copy format. Thank you.


brian.kirkbride at deeperbydesign

Aug 18, 2006, 1:29 PM

Post #9 of 24 (4358 views)
Permalink
Re: ways to do stuff and why [In reply to]

leonard.a.jaffe [at] jpmchase wrote:
> Brian Kirkbride <brian.kirkbride [at] deeperbydesign> @ 08/18/2006 01:57 PM:
> > At this point, if I want code reuse I have two reasonable choices:
> >
> > A) Create business logic modules, ie. MyApp::Logic::CreateTrial, etc
> > B) Write my own business logic methods in
> MyApp::Schema::Trial->create(...)
> >
> > Either is valid and from what I gather Java developers like the Logic
> route. I
> > chose (B) because I already have the classes and the logic is
> *usually* just
> > operating on that class's data model.
>
> [Insert snarky Java comment here]
>
> B couples my business logic too tightly with the ORM. ORMs fall out of
> fancy.
> The whole point of MVC is loose coupling. Method A does not have that
> tight coupling.
> This is a bit of good advice I've picked up along the way:
> Loose coupling of objects. Code to the abstract class (API) not
> the implementation.
>
> Sometimes it helps to forget about ORM's for a minute. The hash or
> array of data returned
> by DBI is still your Model. It you want objects, you have to roll your
> own, around the DBI data.
> Roll your own around the DBIC data, use object composition, rather than
> inheritance. The coupling
> is looser, and that makes your code less brittle.
>

I'm leaning toward this as well, you might have convinced me with the
composition argument. I had been thinking of it in terms of inheriting from the
model.

I've moved from a home-grown ORM to Class::DBI to DBIx::Class in this project's
history. The business logic methods in the model classes had to change each
migration. Not a big deal, because it usually changing ->find to ->retrieve or
something that simple.

But not having to ever change a controller, script or CRON job by way of a set
of Logic:: proxy classes would be nice. Generally these bits don't have to know
much of anything about the model implementation so it hasn't been much to
change. But when iterating over result sets it's hard to avoid the model
implementation specifics.

Maybe I'll spend the weekend whipping up some proxy classes to sit between my
model and the rest. I that the business logic methods in the model would be
moved into these classes as well.

Thanks!
- Brian

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


danielmcbrearty at gmail

Aug 18, 2006, 1:45 PM

Post #10 of 24 (4361 views)
Permalink
Re: ways to do stuff and why [In reply to]

following this with interest. I'm a beginner at this stuff, but the
way I am seeing the problem goes something like this:

1. devise a schema for the data that needs storing that is as robust
and future proof as I can make it.

2. figure out how the front end logic wants to see that data to make
life easy. In other words, what interface objects/methods will make a
decent job of hiding the internal complexities of the data from the
Controller? What objects should exist?

3. have another look at the schema and align the two ways of looking
at the data where appropriate. Then implement code on top of the model
to bridge the two views, implement the API, and protect the db against
crap data ...


--
Daniel McBrearty
email : danielmcbrearty at gmail.com
www.engoi.com : the multi - language vocab trainer
BTW : 0873928131

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


zzbbyy at gmail

Aug 19, 2006, 2:37 AM

Post #11 of 24 (4353 views)
Permalink
Re: ways to do stuff and why [In reply to]

I am glad to see that the 'business logic in the model' side seem now to
prevail in the Catalyst world. It was not so in the past - as this thread
documents:
http://lists.rawmode.org/pipermail/catalyst/2005-August/thread.html#1148
There is also a wiki page on this subject
http://dev.catalyst.perl.org/wiki/NecessaryBackgroundKnowledge

--
Zbyszek

On 8/18/06, Brian Kirkbride <brian.kirkbride [at] deeperbydesign> wrote:
>
> leonard.a.jaffe [at] jpmchase wrote:
> > Brian Kirkbride <brian.kirkbride [at] deeperbydesign> @ 08/18/2006 01:57
> PM:
> > > At this point, if I want code reuse I have two reasonable choices:
> > >
> > > A) Create business logic modules, ie. MyApp::Logic::CreateTrial, etc
> > > B) Write my own business logic methods in
> > MyApp::Schema::Trial->create(...)
> > >
> > > Either is valid and from what I gather Java developers like the Logic
> > route. I
> > > chose (B) because I already have the classes and the logic is
> > *usually* just
> > > operating on that class's data model.
> >
> > [Insert snarky Java comment here]
> >
> > B couples my business logic too tightly with the ORM. ORMs fall out of
> > fancy.
> > The whole point of MVC is loose coupling. Method A does not have that
> > tight coupling.
> > This is a bit of good advice I've picked up along the way:
> > Loose coupling of objects. Code to the abstract class (API) not
> > the implementation.
> >
> > Sometimes it helps to forget about ORM's for a minute. The hash or
> > array of data returned
> > by DBI is still your Model. It you want objects, you have to roll your
> > own, around the DBI data.
> > Roll your own around the DBIC data, use object composition, rather than
> > inheritance. The coupling
> > is looser, and that makes your code less brittle.
> >
>
> I'm leaning toward this as well, you might have convinced me with the
> composition argument. I had been thinking of it in terms of inheriting
> from the
> model.
>
> I've moved from a home-grown ORM to Class::DBI to DBIx::Class in this
> project's
> history. The business logic methods in the model classes had to change
> each
> migration. Not a big deal, because it usually changing ->find to
> ->retrieve or
> something that simple.
>
> But not having to ever change a controller, script or CRON job by way of a
> set
> of Logic:: proxy classes would be nice. Generally these bits don't have
> to know
> much of anything about the model implementation so it hasn't been much to
> change. But when iterating over result sets it's hard to avoid the model
> implementation specifics.
>
> Maybe I'll spend the weekend whipping up some proxy classes to sit between
> my
> model and the rest. I that the business logic methods in the model would
> be
> moved into these classes as well.
>
> Thanks!
> - Brian
>
> _______________________________________________
> List: Catalyst [at] lists
> Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
> Searchable archive:
> http://www.mail-archive.com/catalyst [at] lists/
> Dev site: http://dev.catalyst.perl.org/
>



--
Zbigniew Lukasiak
http://brudnopis.blogspot.com/


dbix-class at trout

Aug 19, 2006, 7:51 AM

Post #12 of 24 (4347 views)
Permalink
Re: ways to do stuff and why [In reply to]

Brian Kirkbride wrote:
> At this point, if I want code reuse I have two reasonable choices:
>
> A) Create business logic modules, ie. MyApp::Logic::CreateTrial, etc
> B) Write my own business logic methods in MyApp::Schema::Trial->create(...)
>
> Either is valid and from what I gather Java developers like the Logic route. I
> chose (B) because I already have the classes and the logic is *usually* just
> operating on that class's data model.

Actually, I tend to have a DBIC::Schema model called something like
'DataStore' and then write logic modules under Model::* that the controllers
call - so "mostly (a), with a bit of (b)"

I think the main bone of contention here is that Len is referring to his
persistence layer as the model, whereas I consider it to just be a persistence
layer - stuff like Model::DBIC::Schema is really only there for simple apps
where what you're modeling *is* the database. If you're modeling a domain,
then your Model::* stuff should be the model of the domain, and whether or not
said model happens to use DBIC stuff as its persistence store should be merely
an implementation detail that the Controller never sees.

--
Matt S Trout Offering custom development, consultancy and support
Technical Director contracts for Catalyst, DBIx::Class and BAST. Contact
Shadowcat Systems Ltd. mst (at) shadowcatsystems.co.uk for more information

+ Help us build a better perl ORM: http://dbix-class.shadowcatsystems.co.uk/ +

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


pagaltzis at gmx

Aug 19, 2006, 8:44 AM

Post #13 of 24 (4355 views)
Permalink
Re: ways to do stuff and why [In reply to]

* Matt S Trout <dbix-class [at] trout> [2006-08-19 16:55]:
> If you're modeling a domain, then your Model::* stuff should be
> the model of the domain, and whether or not said model happens
> to use DBIC stuff as its persistence store should be merely an
> implementation detail that the Controller never sees.

+1

Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


lenjaffe at jaffesystems

Aug 19, 2006, 8:44 AM

Post #14 of 24 (4361 views)
Permalink
Re: ways to do stuff and why [In reply to]

On 8/19/06, Matt S Trout <dbix-class [at] trout> wrote:

> I think the main bone of contention here is that Len is referring to his
> persistence layer as the model, whereas I consider it to just be a
> persistence
> layer - stuff like Model::DBIC::Schema is really only there for simple
> apps
> where what you're modeling *is* the database. If you're modeling a domain,
> then your Model::* stuff should be the model of the domain, and whether or
> not
> said model happens to use DBIC stuff as its persistence store should be
> merely
> an implementation detail that the Controller never sees.


Right. My "Model" is just the data structure holding the raw data. Adding
business domain logic is the bailiwick (love that word) of my Controllers.

I also think that a contention point is whether you, I or anybody else align
our
MVC strictly with Catalyst Ms, Vs, and Cs. Obviously, we've not reached a
consensus, but I think everybody's method has merit, and the key is to work
in your comfort zone, and change when you feel pain.

Whether the Shopping Cart is in the Model, or in the Controller, is an
execise in semantics. It stiil needs to get it's data from someplace
eventually. Which is why I like to use go_get_data() methods in the
business object. The implementation of go_get_em() is data store specific,
but the shopping cart allocates its items abstractly. Same model as
session/authn/authz. Its the same principle of DBI/DBD.

I propose a poker tounament, at Catalyst Expo 2007 (held in Las Vegas
Nevada, USA, or on the French Riviera). Winner gets to define what MVC
really means, and what goes where.

Len.


dbix-class at trout

Aug 19, 2006, 9:34 AM

Post #15 of 24 (4353 views)
Permalink
Re: ways to do stuff and why [In reply to]

A. Pagaltzis wrote:
> * Matt S Trout <dbix-class [at] trout> [2006-08-19 16:55]:
>> If you're modeling a domain, then your Model::* stuff should be
>> the model of the domain, and whether or not said model happens
>> to use DBIC stuff as its persistence store should be merely an
>> implementation detail that the Controller never sees.
>
> +1

This is going to be baked into our new layer-atop-Catalyst that we're working
on, along with something akin to the Jifty Action stuff for mutations of the
model (although without the form handling attached directly, see next para).

So is abstracting out the view-ish logic into a separate layer (think
HTML::Widget on steroids but generalised and with the rendering separate -
we'll be supplying a standard set of TT templates as the default way of
rendering 'em).

The controllers are looking pretty bare - all they really do is grab bits from
the model and instantiate viewport objects with the model objects, so you end
up with the display logic, skinning, model and navigation all separate. Seems
to work pretty nicely.

--
Matt S Trout Offering custom development, consultancy and support
Technical Director contracts for Catalyst, DBIx::Class and BAST. Contact
Shadowcat Systems Ltd. mst (at) shadowcatsystems.co.uk for more information

+ Help us build a better perl ORM: http://dbix-class.shadowcatsystems.co.uk/ +

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


list at markblythe

Aug 21, 2006, 8:20 AM

Post #16 of 24 (4341 views)
Permalink
Re: ways to do stuff and why [In reply to]

> I think the main bone of contention here is that Len is referring to his
> persistence layer as the model, whereas I consider it to just be a persistence
> layer - stuff like Model::DBIC::Schema is really only there for simple apps
> where what you're modeling *is* the database. If you're modeling a domain,
> then your Model::* stuff should be the model of the domain, and whether or not
> said model happens to use DBIC stuff as its persistence store should be merely
> an implementation detail that the Controller never sees.

If the controller truly never sees DBIC stuff, does that mean that
your model logic never returns DBIC objects? For instance, let's say
you have a logic method called findBestFit() that's supposed to return
shoes that fit a given person and activity the best. Would it return
a DBIC ResultSet made up of Shoe row objects, or would findBestFit()
deal with those objects only internally and construct something
non-DBIC for the return?

That's a choice I struggled with up front, and I finally decided that
sticking with DBIC objects made better sense for me than inventing a
whole new layer simply to abstract them and provide similar but not
DBIC-specific interfaces.

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


brian.kirkbride at deeperbydesign

Aug 21, 2006, 8:47 AM

Post #17 of 24 (4323 views)
Permalink
Re: ways to do stuff and why [In reply to]

Mark Blythe wrote:
> If the controller truly never sees DBIC stuff, does that mean that
> your model logic never returns DBIC objects? For instance, let's say
> you have a logic method called findBestFit() that's supposed to return
> shoes that fit a given person and activity the best. Would it return
> a DBIC ResultSet made up of Shoe row objects, or would findBestFit()
> deal with those objects only internally and construct something
> non-DBIC for the return?
>
> That's a choice I struggled with up front, and I finally decided that
> sticking with DBIC objects made better sense for me than inventing a
> whole new layer simply to abstract them and provide similar but not
> DBIC-specific interfaces.
>

I'm right there with you - I want to abstract but without reinventing the wheel.

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


dbix-class at trout

Aug 21, 2006, 8:56 AM

Post #18 of 24 (4345 views)
Permalink
Re: ways to do stuff and why [In reply to]

Mark Blythe wrote:
>> I think the main bone of contention here is that Len is referring to his
>> persistence layer as the model, whereas I consider it to just be a persistence
>> layer - stuff like Model::DBIC::Schema is really only there for simple apps
>> where what you're modeling *is* the database. If you're modeling a domain,
>> then your Model::* stuff should be the model of the domain, and whether or not
>> said model happens to use DBIC stuff as its persistence store should be merely
>> an implementation detail that the Controller never sees.
>
> If the controller truly never sees DBIC stuff, does that mean that
> your model logic never returns DBIC objects? For instance, let's say
> you have a logic method called findBestFit() that's supposed to return
> shoes that fit a given person and activity the best. Would it return
> a DBIC ResultSet made up of Shoe row objects, or would findBestFit()
> deal with those objects only internally and construct something
> non-DBIC for the return?
>
> That's a choice I struggled with up front, and I finally decided that
> sticking with DBIC objects made better sense for me than inventing a
> whole new layer simply to abstract them and provide similar but not
> DBIC-specific interfaces.

I tend to return the DBIC objects but make sure the controller only ever
interacts with *semantic* methods rather than the DBIC-specific
find/search/etc. so I could swap it out for such an extra layer if I ever need to.

--
Matt S Trout Offering custom development, consultancy and support
Technical Director contracts for Catalyst, DBIx::Class and BAST. Contact
Shadowcat Systems Ltd. mst (at) shadowcatsystems.co.uk for more information

+ Help us build a better perl ORM: http://dbix-class.shadowcatsystems.co.uk/ +

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


leonard.a.jaffe at jpmchase

Aug 21, 2006, 9:22 AM

Post #19 of 24 (4325 views)
Permalink
Re: ways to do stuff and why [In reply to]

"Mark Blythe" <list [at] markblythe> 08/21/2006 :
> > Matt Trout Wrote:
> > I think the main bone of contention here is that Len is referring to
his
> > persistence layer as the model, whereas I consider it to just be a
persistence
> > layer - stuff like Model::DBIC::Schema is really only there for simple
apps
> > where what you're modeling *is* the database. If you're modeling a
domain,
> > then your Model::* stuff should be the model of the domain, and
whether or not
> > said model happens to use DBIC stuff as its persistence store should
be merely
> > an implementation detail that the Controller never sees.
>
> If the controller truly never sees DBIC stuff, does that mean that
> your model logic never returns DBIC objects? For instance, let's say
> you have a logic method called findBestFit() that's supposed to return
> shoes that fit a given person and activity the best. Would it return
> a DBIC ResultSet made up of Shoe row objects, or would findBestFit()
> deal with those objects only internally and construct something
> non-DBIC for the return?


In my reality, I want findBestFit() to return a set of Shoes. The Shoe can
be a
DBIC mydb::Shoe row object, from which I'm likely to call vanilla
accessors,
or they will be MyDomain::Shoe objects, each one decorating a mydb::Shoe
object,
and containing more shoe logic.

findBestFit() should return objects that conform to your abstract notion
of a shoe.
Then you're insulated from your data source.

Your business logic should deal with Shoes. If using a DBIC Shoe row
works for you,
that's totally cool. But your business logic should contain one thin layer
to insulate
findBestFit() from the gory details of your data store.

Again, I'll make the comparison to DBI/DBD which emulated ODBC in that you
program
to a general API, and the vendor specific stuff is under the hood. So
now, your ORM
returns objects instead of hashrefs. But the specific method of setting up
a query
differs from ORM to ORM. So you either choose to code to your ORM's API,
or write
a ORM independent access layer.

In my MVC world, the Model is only the raw data, the Controller is the
business logic,
and the view is the display. The model simply gets the data from wherever
it is stored,
and puts it back when it's done. The view shows the data in the model, to
the
logs, to the HTML page, etc. The controller applies the business logic to
the model.
Sometimes the controller changes the view, other times it does its job
silently.
The controller wants to deal in abstractions: Shoes, Stockroom,
ShoppingCart, Discount.
It wants to execute Stockroom.findBestFit(myBigFeet.measurments()) and get
back a set
of Shoes to manipulate.

In Catalyst, the model tends to map one-to-one to my idea of a model. It
interacts with
my data store. The view maps well also. Here's my stash, work your magic.
Now the trick
with the catalyst controller, is not to put vast amounts of business logic
in them. Use
them for handling web parameters, but then allocate business objects and
manipulate them.
It's better to instantiate a big wrapper object, ShoeStore and execute
ShoeStore.gotAnyAirJordansInMySize(MyFeet), returning Shoes, which then
get plugged into
stash for the view to use, than to write the whole search in the catalyst
action. Better,
because then you can call you business objects from any perl program
regardless of the
user interface.


Len.
My fingers hurt.


-----------------------------------------
This transmission may contain information that is privileged,
confidential, legally privileged, and/or exempt from disclosure
under applicable law. If you are not the intended recipient, you
are hereby notified that any disclosure, copying, distribution, or
use of the information contained herein (including any reliance
thereon) is STRICTLY PROHIBITED. Although this transmission and
any attachments are believed to be free of any virus or other
defect that might affect any computer system into which it is
received and opened, it is the responsibility of the recipient to
ensure that it is virus free and no responsibility is accepted by
JPMorgan Chase & Co., its subsidiaries and affiliates, as
applicable, for any loss or damage arising in any way from its use.
If you received this transmission in error, please immediately
contact the sender and destroy the material in its entirety,
whether in electronic or hard copy format. Thank you.


leonard.a.jaffe at jpmchase

Aug 21, 2006, 9:27 AM

Post #20 of 24 (4330 views)
Permalink
Re: ways to do stuff and why [In reply to]

Matt S Trout <dbix-class [at] trout> 08/21/2006 :

> I tend to return the DBIC objects but make sure the controller only ever

> interacts with *semantic* methods rather than the DBIC-specific
> find/search/etc. so I could swap it out for such an extra layer if I
ever need to.

I think we just agreed on something :-)


-----------------------------------------
This transmission may contain information that is privileged,
confidential, legally privileged, and/or exempt from disclosure
under applicable law. If you are not the intended recipient, you
are hereby notified that any disclosure, copying, distribution, or
use of the information contained herein (including any reliance
thereon) is STRICTLY PROHIBITED. Although this transmission and
any attachments are believed to be free of any virus or other
defect that might affect any computer system into which it is
received and opened, it is the responsibility of the recipient to
ensure that it is virus free and no responsibility is accepted by
JPMorgan Chase & Co., its subsidiaries and affiliates, as
applicable, for any loss or damage arising in any way from its use.
If you received this transmission in error, please immediately
contact the sender and destroy the material in its entirety,
whether in electronic or hard copy format. Thank you.


zzbbyy at gmail

Aug 22, 2006, 12:26 AM

Post #21 of 24 (4346 views)
Permalink
Re: ways to do stuff and why [In reply to]

There is one practical argument for having the business logic in the model -
it is the necessity of using it from command line/cron job tools. I have
not yet heard a similar argument from the other side - that is for having
the logic in the controller.

--
Zbyszek

On 8/21/06, leonard.a.jaffe [at] jpmchase <leonard.a.jaffe [at] jpmchase>
wrote:
>
>
> "Mark Blythe" <list [at] markblythe> 08/21/2006 :
>
> > > Matt Trout Wrote:
> > > I think the main bone of contention here is that Len is referring to
> his
> > > persistence layer as the model, whereas I consider it to just be a
> persistence
> > > layer - stuff like Model::DBIC::Schema is really only there for simple
> apps
> > > where what you're modeling *is* the database. If you're modeling a
> domain,
> > > then your Model::* stuff should be the model of the domain, and
> whether or not
> > > said model happens to use DBIC stuff as its persistence store should
> be merely
> > > an implementation detail that the Controller never sees.
> >
> > If the controller truly never sees DBIC stuff, does that mean that
> > your model logic never returns DBIC objects? For instance, let's say
> > you have a logic method called findBestFit() that's supposed to return
> > shoes that fit a given person and activity the best. Would it return
> > a DBIC ResultSet made up of Shoe row objects, or would findBestFit()
> > deal with those objects only internally and construct something
> > non-DBIC for the return?
>
>
> In my reality, I want findBestFit() to return a set of Shoes. The Shoe can
> be a
> DBIC mydb::Shoe row object, from which I'm likely to call vanilla
> accessors,
> or they will be MyDomain::Shoe objects, each one decorating a mydb::Shoe
> object,
> and containing more shoe logic.
>
> findBestFit() should return objects that conform to your abstract notion
> of a shoe.
> Then you're insulated from your data source.
>
> Your business logic should deal with Shoes. If using a DBIC Shoe row
> works for you,
> that's totally cool. But your business logic should contain one thin layer
> to insulate
> findBestFit() from the gory details of your data store.
>
> Again, I'll make the comparison to DBI/DBD which emulated ODBC in that you
> program
> to a general API, and the vendor specific stuff is under the hood. So
> now, your ORM
> returns objects instead of hashrefs. But the specific method of setting up
> a query
> differs from ORM to ORM. So you either choose to code to your ORM's API,
> or write
> a ORM independent access layer.
>
> In my MVC world, the Model is only the raw data, the Controller is the
> business logic,
> and the view is the display. The model simply gets the data from wherever
> it is stored,
> and puts it back when it's done. The view shows the data in the model, to
> the
> logs, to the HTML page, etc. The controller applies the business logic to
> the model.
> Sometimes the controller changes the view, other times it does its job
> silently.
> The controller wants to deal in abstractions: Shoes, Stockroom,
> ShoppingCart, Discount.
> It wants to execute Stockroom.findBestFit(myBigFeet.measurments()) and get
> back a set
> of Shoes to manipulate.
>
> In Catalyst, the model tends to map one-to-one to my idea of a model. It
> interacts with
> my data store. The view maps well also. Here's my stash, work your magic.
> Now the trick
> with the catalyst controller, is not to put vast amounts of business logic
> in them. Use
> them for handling web parameters, but then allocate business objects and
> manipulate them.
> It's better to instantiate a big wrapper object, ShoeStore and execute
> ShoeStore.gotAnyAirJordansInMySize(MyFeet), returning Shoes, which then
> get plugged into
> stash for the view to use, than to write the whole search in the catalyst
> action. Better,
> because then you can call you business objects from any perl program
> regardless of the
> user interface.
>
>
> Len.
> My fingers hurt.
>
> ------------------------------
>
>
>
> This transmission may contain information that is privileged,
> confidential, legally privileged, and/or exempt from disclosure
> under applicable law. If you are not the intended recipient, you
> are hereby notified that any disclosure, copying, distribution, or
> use of the information contained herein (including any reliance
> thereon) is STRICTLY PROHIBITED. Although this transmission and
> any attachments are believed to be free of any virus or other
> defect that might affect any computer system into which it is
> received and opened, it is the responsibility of the recipient to
> ensure that it is virus free and no responsibility is accepted by
> JPMorgan Chase & Co., its subsidiaries and affiliates, as
> applicable, for any loss or damage arising in any way from its use.
> If you received this transmission in error, please immediately
> contact the sender and destroy the material in its entirety,
> whether in electronic or hard copy format. Thank you.
>
> _______________________________________________
> List: Catalyst [at] lists
> Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
> Searchable archive:
> http://www.mail-archive.com/catalyst [at] lists/
> Dev site: http://dev.catalyst.perl.org/
>
>
>


--
Zbigniew Lukasiak
http://brudnopis.blogspot.com/


kaare at jasonic

Aug 22, 2006, 12:58 AM

Post #22 of 24 (4332 views)
Permalink
Re: ways to do stuff and why [In reply to]

> There is one practical argument for having the business logic in the model
> - it is the necessity of using it from command line/cron job tools. I have

But it's easily overcome if you put your logic in separate modules. I don't
think that practical problems like this should dictate your design
philosophy.

More than that, it seems to me that it's a major shortcoming of the MVC model
that there's no real good place to put the real beef, the logic. i'd like to
keep the model as a persistence layer. The logic I'd put there should only be
concerned with keeping data consistent.
The controller should only be interested in moving things around and the
viewer is completely out of the question :-)
So in my view, business logic, rules, computations (other than simple data
twisting) and other stuff that has to be flexible doesn't really fit in. Of
course you can have it in the model, but then the model really has two
layers, a persistence and a processing layer.

Each developer has to solve that independently at least until Catalyst will
shine as the first MLVC (Model-Logic-View-Controller) system ;-)

--

Med venlig hilsen
Kaare Rasmussen, Jasonic

Jasonic Telefon: +45 3816 2582
Nordre Fasanvej 12
2000 Frederiksberg Email: kaare [at] jasonic

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


zzbbyy at gmail

Aug 22, 2006, 1:17 AM

Post #23 of 24 (4324 views)
Permalink
Re: ways to do stuff and why [In reply to]

If I reformulate my statement as follow:

There is one practical argument not to have the business logic in the
controller - it is ...

Can we agree?

The result I would like to get from this conversation is that I don't see
some point of time controllers with business logic in them at CPAN.

--
Zbyszek

On 8/22/06, Kaare Rasmussen <kaare [at] jasonic> wrote:
>
> > There is one practical argument for having the business logic in the
> model
> > - it is the necessity of using it from command line/cron job tools. I
> have
>
> But it's easily overcome if you put your logic in separate modules. I
> don't
> think that practical problems like this should dictate your design
> philosophy.
>
> More than that, it seems to me that it's a major shortcoming of the MVC
> model
> that there's no real good place to put the real beef, the logic. i'd like
> to
> keep the model as a persistence layer. The logic I'd put there should only
> be
> concerned with keeping data consistent.
> The controller should only be interested in moving things around and the
> viewer is completely out of the question :-)
> So in my view, business logic, rules, computations (other than simple data
> twisting) and other stuff that has to be flexible doesn't really fit in.
> Of
> course you can have it in the model, but then the model really has two
> layers, a persistence and a processing layer.
>
> Each developer has to solve that independently at least until Catalyst
> will
> shine as the first MLVC (Model-Logic-View-Controller) system ;-)
>
> --
>
> Med venlig hilsen
> Kaare Rasmussen, Jasonic
>
> Jasonic Telefon: +45 3816 2582
> Nordre Fasanvej 12
> 2000 Frederiksberg Email: kaare [at] jasonic
>
> _______________________________________________
> List: Catalyst [at] lists
> Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
> Searchable archive:
> http://www.mail-archive.com/catalyst [at] lists/
> Dev site: http://dev.catalyst.perl.org/
>



--
Zbigniew Lukasiak
http://brudnopis.blogspot.com/


dbix-class at trout

Aug 22, 2006, 2:34 AM

Post #24 of 24 (4326 views)
Permalink
Re: ways to do stuff and why [In reply to]

Kaare Rasmussen wrote:
>> There is one practical argument for having the business logic in the model
>> - it is the necessity of using it from command line/cron job tools. I have
>
> But it's easily overcome if you put your logic in separate modules. I don't
> think that practical problems like this should dictate your design
> philosophy.
>
> More than that, it seems to me that it's a major shortcoming of the MVC model
> that there's no real good place to put the real beef, the logic. i'd like to
> keep the model as a persistence layer. The logic I'd put there should only be
> concerned with keeping data consistent.
> The controller should only be interested in moving things around and the
> viewer is completely out of the question :-)
> So in my view, business logic, rules, computations (other than simple data
> twisting) and other stuff that has to be flexible doesn't really fit in. Of
> course you can have it in the model, but then the model really has two
> layers, a persistence and a processing layer.

Actually, arguably the Model should be the processing and logic layer - it's a
*model* of your domain. That it talks to a persistence store of some sort (or
to something completely different, e.g. a set of network servers in the case
of an IM app) is merely an implementation detail.

--
Matt S Trout Offering custom development, consultancy and support
Technical Director contracts for Catalyst, DBIx::Class and BAST. Contact
Shadowcat Systems Ltd. mst (at) shadowcatsystems.co.uk for more information

+ Help us build a better perl ORM: http://dbix-class.shadowcatsystems.co.uk/ +

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/

Catalyst users RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.