Hi, I''m a newbie in both Ruby and Ruby on Rails. I finished the Ruby on Rail Tutorial on Todo list and it was great. But, now I''m trying to understand the logic behind it, that is something that is not obvious on how each one of them ties together. Is there a flowchart that shows how the inner working of Ruby on Rails? In another words, let''s suppose we consider the following simple scenarios to recreate the logic behind Ruby on Rails, Scenario 1: Using MVC to display different words from commandline" Purpose : IMO, this exercise will show how to put Model, View, and Controller in concert to take input from commandline, massage the data, and then view it on the screen. Goal: To exercise the mindset/design-methodology that is to know what need to be done first, second, third, etc ... for this MVC to work. e.g: do we need a class for reading data or just a method and how we classify it as a Controller, or a Model? View, should we create a View class or a method if we will have 3 ways viewing the text. Scenario 2: Using MVC to display data from a database or multi-database Purpose: similar to the above Goal : similar to the above, assuming that we have a database and we need to create a method or a class of connecting to a db, read data, find data, delete data, list data, etc. Where do we put this utilities in the MVC scheme as? Controller? How do we tie this in the program flow? Sorry if I''m rambling a bit, but the idea is I''m trying to understand the inner working of Ruby on Rails, therefore I can better utilize its features. Thanks
On Thu, 13 Jan 2005 15:50:20 -0500, Sarah Tanembaum <sarahtanembaum-/E1597aS9LQAvxtiuMwx3w@public.gmane.org> wrote:> Hi, I''m a newbie in both Ruby and Ruby on Rails. I finished the Ruby on > Rail Tutorial on Todo list and it was great. But, now I''m trying to > understand the logic behind it, that is something that is not obvious on > how each one of them ties together. > > Is there a flowchart that shows how the inner working of Ruby on Rails? > In another words, let''s suppose we consider the following simple > scenarios to recreate the logic behind Ruby on Rails, > > Scenario 1: Using MVC to display different words from commandline" > Purpose : IMO, this exercise will show how to put Model, View, > and Controller in concert to take input from commandline, > massage the data, and then view it on the screen. > > Goal: To exercise the mindset/design-methodology that is to know > what need to be done first, second, third, etc ... for this > MVC to work. e.g: do we need a class for reading data or > just a method and how we classify it as a Controller, or a > Model? View, should we create a View class or a method if we > will have 3 ways viewing the text. > > Scenario 2: Using MVC to display data from a database or multi-database > Purpose: similar to the above > Goal : similar to the above, assuming that we have a database > and we need to create a method or a class of connecting > to a db, read data, find data, delete data, list data, etc. > Where do we put this utilities in the MVC scheme as? > Controller? How do we tie this in the program flow? > > Sorry if I''m rambling a bit, but the idea is I''m trying to understand > the inner working of Ruby on Rails, therefore I can better utilize its > features. > > ThanksI''d imagine that the controller and view parts are designed to be used through a web browser, not through the command line.
> I''d imagine that the controller and view parts are designed to be used > through a web browser, not through the command line.Taking it a step further, the command line application is a completely different user interface, and it *shouldn''t* share the UI releated components (i.e. View and Controller). The scripts I''ve built use Active Record directly, i.e: User.new_users.each do |user| user.welcome #sends welcome email end This highlights the importance of having your business logic in your model, not in your controllers. -- Cheers Koz
On Jan 14, 2005, at 4:06 AM, Michael Koziarski wrote:>> I''d imagine that the controller and view parts are designed to be used >> through a web browser, not through the command line. > > Taking it a step further, the command line application is a > completely different user interface, and it *shouldn''t* share the UI > releated components (i.e. View and Controller). > > The scripts I''ve built use Active Record directly, i.e: > > User.new_users.each do |user| > user.welcome #sends welcome email > end > > This highlights the importance of having your business logic in your > model, not in your controllers.I agree that it is bad having the logic in controllers. But I also don''t like to put business logic in in the domain model. I try to keep the model objects as lightweight as they can be; if I add logic to them it is usuall for handling relationships between model objects or simple getter/setter logic. My approach is this: I move all business logic, the glue that actually puts model objects together to make sense as a whole, in a Service Layer. Personally I think this is a much cleaner design because it doesn''t pollute the domain model with application logic. http://www.martinfowler.com/eaaCatalog/serviceLayer.html It also makes it easier to export the application logic to different modules/layers that don''t have to know all the details about the domain model. Lastly, I''m not sure how this is handled in Rails, in the Java world this setup allows me to do transaction demarcation in one place since i simply annotate the methods in the service layer with the proper transaction strategy. For me, putting logic in the domain model is a big step backwards. S.
> I agree that it is bad having the logic in controllers. But I also > don''t like to put business logic in in the domain model. I try to keep > the model objects as lightweight as they can be; if I add logic to them > it is usuall for handling relationships between model objects or simple > getter/setter logic. > > My approach is this: I move all business logic, the glue that actually > puts model objects together to make sense as a whole, in a Service > Layer. Personally I think this is a much cleaner design because it > doesn''t pollute the domain model with application logic. > > http://www.martinfowler.com/eaaCatalog/serviceLayer.htmlI can quote Fowler too ;). What you''re describing is an anemic domain model, and the style of programming is quite common in java (IOC containers especially). http://www.martinfowler.com/bliki/AnemicDomainModel.html "In general, the more behavior you find in the services, the more likely you are to be robbing yourself of the benefits of a domain model. If all your logic is in services, you''ve robbed yourself blind."> It also makes it easier to export the application logic to different > modules/layers that don''t have to know all the details about the domain > model. > > Lastly, I''m not sure how this is handled in Rails, in the Java world > this setup allows me to do transaction demarcation in one place since i > simply annotate the methods in the service layer with the proper > transaction strategy.I''d suggest that transaction demarcation is typically a UI thing> For me, putting logic in the domain model is a big step backwards.The business logic should absolutely live in the domain model, that''s why we have a domain model. These big ''service layer'' systems are just COBOL programming with fancy record types. We can blame Sun for that though, stupid EJBs. ;)> S. > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Cheers Koz
Definition of service layer from the Fowler link: "Defines an application''s boundary with a layer of services that establishes a set of available operations and coordinates the application''s response in each operation." You could say, depending on definitions, that application logic goes in the service layer (application layer) and business logic goes in the domain model. That''s can be confusing though, since many people equate business and application logic. And, of course, it depends on the domain of the software being developed and the nature of the application. I''ve seen cases where an anemic data model worked wonders in a mid-size app. This app has very volitile business rules, and the model needs lots of extensions for different clients. The service layer has a plugin model allows for business rules to be added in an replaceable/customizable manner in a somewhat procedural manner. OO benefits are mostly in the world of typing. Regards, Nick On Fri, 14 Jan 2005 12:03:23 -0800, Michael Koziarski <koziarski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > I agree that it is bad having the logic in controllers. But I also > > don''t like to put business logic in in the domain model. I try to keep > > the model objects as lightweight as they can be; if I add logic to them > > it is usuall for handling relationships between model objects or simple > > getter/setter logic. > > > > My approach is this: I move all business logic, the glue that actually > > puts model objects together to make sense as a whole, in a Service > > Layer. Personally I think this is a much cleaner design because it > > doesn''t pollute the domain model with application logic. > > > > http://www.martinfowler.com/eaaCatalog/serviceLayer.html > > I can quote Fowler too ;). What you''re describing is an anemic domain > model, and the style of programming is quite common in java (IOC > containers especially). > > http://www.martinfowler.com/bliki/AnemicDomainModel.html > > "In general, the more behavior you find in the services, the more > likely you are to be robbing yourself of the benefits of a domain > model. If all your logic is in services, you''ve robbed yourself > blind." > > > It also makes it easier to export the application logic to different > > modules/layers that don''t have to know all the details about the domain > > model. > > > > Lastly, I''m not sure how this is handled in Rails, in the Java world > > this setup allows me to do transaction demarcation in one place since i > > simply annotate the methods in the service layer with the proper > > transaction strategy. > > I''d suggest that transaction demarcation is typically a UI thing > > > For me, putting logic in the domain model is a big step backwards. > > The business logic should absolutely live in the domain model, that''s > why we have a domain model. These big ''service layer'' systems are > just COBOL programming with fancy record types. We can blame Sun for > that though, stupid EJBs. ;) > > > S. > > > > _______________________________________________ > > Rails mailing list > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > > -- > Cheers > > Koz > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Nicholas Van Weerdenburg
> Definition of service layer from the Fowler link: > > "Defines an application''s boundary with a layer of services that > establishes a set of available operations and coordinates the > application''s response in each operation." > > You could say, depending on definitions, that application logic goes > in the service layer (application layer) and business logic goes in > the domain model. That''s can be confusing though, since many people > equate business and application logic.What''s really interesting from the fowler link, is that he''s not talking about the service layer being the place the work gets done, the diagram contains a ''domain model''. http://www.martinfowler.com/eaaCatalog/domainModel.html look at the definition of domain model. Look at the behaviour there. recognizedRevenue, calculateRecognitions. All living in the domain.> And, of course, it depends on the domain of the software being > developed and the nature of the application. I''ve seen cases where an > anemic data model worked wonders in a mid-size app.Absolutely. There''s more COBOL code produced each year than any other language, this output is powering applications, producing value to the business that pay for it. Procedural programming with ''record'' types can clearly work, and in some circumstances it can work wonders. However, if you''re building an OO app, you should have logic in your domain model. That''s the whole point of a domain model. If you''re just going to have procedures operating on data, you''re probably better off using stored procedures or something. Logic in the domain isn''t a huge step back, it''s a huge step forward.> Regards, > Nick > > On Fri, 14 Jan 2005 12:03:23 -0800, Michael Koziarski > <koziarski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > I agree that it is bad having the logic in controllers. But I also > > > don''t like to put business logic in in the domain model. I try to keep > > > the model objects as lightweight as they can be; if I add logic to them > > > it is usuall for handling relationships between model objects or simple > > > getter/setter logic. > > > > > > My approach is this: I move all business logic, the glue that actually > > > puts model objects together to make sense as a whole, in a Service > > > Layer. Personally I think this is a much cleaner design because it > > > doesn''t pollute the domain model with application logic. > > > > > > http://www.martinfowler.com/eaaCatalog/serviceLayer.html > > > > I can quote Fowler too ;). What you''re describing is an anemic domain > > model, and the style of programming is quite common in java (IOC > > containers especially). > > > > http://www.martinfowler.com/bliki/AnemicDomainModel.html > > > > "In general, the more behavior you find in the services, the more > > likely you are to be robbing yourself of the benefits of a domain > > model. If all your logic is in services, you''ve robbed yourself > > blind." > > > > > It also makes it easier to export the application logic to different > > > modules/layers that don''t have to know all the details about the domain > > > model. > > > > > > Lastly, I''m not sure how this is handled in Rails, in the Java world > > > this setup allows me to do transaction demarcation in one place since i > > > simply annotate the methods in the service layer with the proper > > > transaction strategy. > > > > I''d suggest that transaction demarcation is typically a UI thing > > > > > For me, putting logic in the domain model is a big step backwards. > > > > The business logic should absolutely live in the domain model, that''s > > why we have a domain model. These big ''service layer'' systems are > > just COBOL programming with fancy record types. We can blame Sun for > > that though, stupid EJBs. ;) > > > > > S. > > > > > > _______________________________________________ > > > Rails mailing list > > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > > > > > > -- > > Cheers > > > > Koz > > _______________________________________________ > > Rails mailing list > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > -- > Nicholas Van Weerdenburg >-- Cheers Koz
MVC is a deadly acronym. The C has a bunch of different meanings, most of which don''t map to the original Smalltalk meaning- the user interface controller. In this model, you could swap a web controller for a command-line controller. However, this is inapplicable to most modern usages of "MVC" and the defined responsbilities of each letter. http://c2.com/cgi/wiki?ModelViewController is an interesting overview- especially the link to history. It still hurts my head to read it though. The "Design Patterns" book explains why they don''t define a "MVC" pattern, which is interesting. If I recall, it was the Oberver and Strategy pattern that were the core components (though observer usually doesn''t some into the play in web apps) . To confuse things more, some Rational literature talks about EBC- entity classes, boundary classes, and controller classes. It''s a technique where you look at a general class diagram and define which are entity classes, boundary classes, and controller classes. This is a great technique for analyzing a class diagram and your allocation of responsibilities to different classes- it''s somewhat of a genaral MVC that applies to designs in a broader sense. Applying it to MVC, it maps somewhat like B=View, E=Model, and C somewhat maps to how people use MVC nowadays. It is a strategy class that mediates flow and iteraction with the model at a high level, ultimately delivering it to the view. This is the way I like to think about it- the controller is the strategy/algorithm that takes the data from the model and gets it to the view. Why do it this way? Well, in one respect it''s about responsibilities- it doesn''t fit in the view or the model, so it goes in a new object. This is a common theme in assigning responsibilities- if you can''t comfortably put responsibility into a model or view/boundary class, then maybe you a controller is needed. Staying DRY (don''t repeat yourself) also influences this- if there is a missing controller, there is often duplicatation among views and/or models. This keeps also keeps the model clean, Imagine a Document class with 700 methods because all the view creation logic is in there. And you don''t know which methods are to be used for which process- the process context is lost. And it keeps the view clean and DRY- if the view was an aggregation of document + workflow model attributes, where would the logic fit in the model? You''d end up stuffing it in the view, which means that your need to duplicate it across similar views. And finally, it keeps the code readable and self-documenting. One draw-back of object-orientation is that it doesn''t represent the procedural flow of logic well. It''s very hard to understand what and application does by looking at class diagram. Sequence diagrams , activity diagrams, and use cases provide this, but it''s not very DRY, and the code isn''t self-evident, making it hard to program. By have classes that present the flow/strategy of the application interactions ( the controller/strategy class), it''s easier to understand the code. DRY and appropriate responsbilities also lead fairly naturally to low coupling and high cohesion, which are two other goals/benefits of the MVC design pattern. So for me, I understand MVC by combining the concepts of EBC (entity-boundary-controiller), the Design Pattern''s book overview of MVC (Strategy, Observer), and the core concepts of DRY and appropriate allocation of responsibility. And this is how I look at rails controllers- flow logic as a strategy pattern for getting data back and forth between models and views. In some respects it also acts as a service/application layer as defined further down in this thread (all the references to Martin Fowler). Though on that topic, its worth considering that Rails, and Ruby, being so expressive and concise, make some traditional patterns seem a bit overblown- especially the J2EE ones. On a similar topic I once read an article where the author postulated that Lisp doesn''t have a pattern community because patterns are so naturally expressed in the Lisp-style of programming, they are almost subconcious. This, to me, is a large stretch, but it is food for thought. Regards, Nick On Thu, 13 Jan 2005 15:50:20 -0500, Sarah Tanembaum <sarahtanembaum-/E1597aS9LQAvxtiuMwx3w@public.gmane.org> wrote:> Hi, I''m a newbie in both Ruby and Ruby on Rails. I finished the Ruby on > Rail Tutorial on Todo list and it was great. But, now I''m trying to > understand the logic behind it, that is something that is not obvious on > how each one of them ties together. > > Is there a flowchart that shows how the inner working of Ruby on Rails? > In another words, let''s suppose we consider the following simple > scenarios to recreate the logic behind Ruby on Rails, > > Scenario 1: Using MVC to display different words from commandline" > Purpose : IMO, this exercise will show how to put Model, View, > and Controller in concert to take input from commandline, > massage the data, and then view it on the screen. > > Goal: To exercise the mindset/design-methodology that is to know > what need to be done first, second, third, etc ... for this > MVC to work. e.g: do we need a class for reading data or > just a method and how we classify it as a Controller, or a > Model? View, should we create a View class or a method if we > will have 3 ways viewing the text. > > Scenario 2: Using MVC to display data from a database or multi-database > Purpose: similar to the above > Goal : similar to the above, assuming that we have a database > and we need to create a method or a class of connecting > to a db, read data, find data, delete data, list data, etc. > Where do we put this utilities in the MVC scheme as? > Controller? How do we tie this in the program flow? > > Sorry if I''m rambling a bit, but the idea is I''m trying to understand > the inner working of Ruby on Rails, therefore I can better utilize its > features. > > Thanks > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Nicholas Van Weerdenburg
One last point- another confusing aspect of controllers is that looking at rails you might think that the domain model = ActiveRecord (e.g. persitable entities) only by simple virtue of ActiveRecord being the core functionality provided in the model area. In general, the domain model is more then just the persitable entities- it can/may contain controllers of the EBC type specifically for the domain model. So, you might have controllers of the EBC kind in the domain model, and the Rails controllers are higher level for the application layer logic (e.g. view specific). If you don''t make this distinction, you may still run into "responsibility fog" when writing code. Also, it may not be an issue in smaller codebases- the Rails controllers may suffice for the domain model controllers by doing double duty. However, at some point, this may cause your code to break down somewhat, with DRY violations, responsbility confusion, and so on. I know that Rails trys to simplify things, so I''m not exactly sure of it''s design philosophy here- is the model usually just persitables? Can anyone set me straight on this? Thanks, Nick On Fri, 14 Jan 2005 17:52:38 -0500, Nicholas Van Weerdenburg <vanweerd-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> MVC is a deadly acronym. The C has a bunch of different meanings, most > of which don''t map to the original Smalltalk meaning- the user > interface controller. In this model, you could swap a web controller > for a command-line controller. However, this is inapplicable to most > modern usages of "MVC" and the defined responsbilities of each letter. > > http://c2.com/cgi/wiki?ModelViewController is an interesting overview- > especially the link to history. It still hurts my head to read it > though. > > The "Design Patterns" book explains why they don''t define a "MVC" > pattern, which is interesting. If I recall, it was the Oberver and > Strategy pattern that were the core components (though observer > usually doesn''t some into the play in web apps) . > > To confuse things more, some Rational literature talks about EBC- > entity classes, boundary classes, and controller classes. It''s a > technique where you look at a general class diagram and define which > are entity classes, boundary classes, and controller classes. This is > a great technique for analyzing a class diagram and your allocation of > responsibilities to different classes- it''s somewhat of a genaral MVC > that applies to designs in a broader sense. > > Applying it to MVC, it maps somewhat like B=View, E=Model, and C > somewhat maps to how people use MVC nowadays. It is a strategy class > that mediates flow and iteraction with the model at a high level, > ultimately delivering it to the view. > > This is the way I like to think about it- the controller is the > strategy/algorithm that takes the data from the model and gets it to > the view. > > Why do it this way? Well, in one respect it''s about responsibilities- > it doesn''t fit in the view or the model, so it goes in a new object. > This is a common theme in assigning responsibilities- if you can''t > comfortably put responsibility into a model or view/boundary class, > then maybe you a controller is needed. Staying DRY (don''t repeat > yourself) also influences this- if there is a missing controller, > there is often duplicatation among views and/or models. > > This keeps also keeps the model clean, Imagine a Document class with > 700 methods because all the view creation logic is in there. And you > don''t know which methods are to be used for which process- the process > context is lost. > > And it keeps the view clean and DRY- if the view was an aggregation of > document + workflow model attributes, where would the logic fit in the > model? You''d end up stuffing it in the view, which means that your > need to duplicate it across similar views. > > And finally, it keeps the code readable and self-documenting. One > draw-back of object-orientation is that it doesn''t represent the > procedural flow of logic well. It''s very hard to understand what and > application does by looking at class diagram. Sequence diagrams , > activity diagrams, and use cases provide this, but it''s not very DRY, > and the code isn''t self-evident, making it hard to program. By have > classes that present the flow/strategy of the application interactions > ( the controller/strategy class), it''s easier to understand the code. > > DRY and appropriate responsbilities also lead fairly naturally to low > coupling and high cohesion, which are two other goals/benefits of the > MVC design pattern. > > So for me, I understand MVC by combining the concepts of EBC > (entity-boundary-controiller), the Design Pattern''s book overview of > MVC (Strategy, Observer), and the core concepts of DRY and appropriate > allocation of responsibility. > > And this is how I look at rails controllers- flow logic as a strategy > pattern for getting data back and forth between models and views. In > some respects it also acts as a service/application layer as defined > further down in this thread (all the references to Martin Fowler). > Though on that topic, its worth considering that Rails, and Ruby, > being so expressive and concise, make some traditional patterns seem a > bit overblown- especially the J2EE ones. On a similar topic I once > read an article where the author postulated that Lisp doesn''t have a > pattern community because patterns are so naturally expressed in the > Lisp-style of programming, they are almost subconcious. This, to me, > is a large stretch, but it is food for thought. > > Regards, > Nick > > On Thu, 13 Jan 2005 15:50:20 -0500, Sarah Tanembaum > <sarahtanembaum-/E1597aS9LQAvxtiuMwx3w@public.gmane.org> wrote: > > Hi, I''m a newbie in both Ruby and Ruby on Rails. I finished the Ruby on > > Rail Tutorial on Todo list and it was great. But, now I''m trying to > > understand the logic behind it, that is something that is not obvious on > > how each one of them ties together. > > > > Is there a flowchart that shows how the inner working of Ruby on Rails? > > In another words, let''s suppose we consider the following simple > > scenarios to recreate the logic behind Ruby on Rails, > > > > Scenario 1: Using MVC to display different words from commandline" > > Purpose : IMO, this exercise will show how to put Model, View, > > and Controller in concert to take input from commandline, > > massage the data, and then view it on the screen. > > > > Goal: To exercise the mindset/design-methodology that is to know > > what need to be done first, second, third, etc ... for this > > MVC to work. e.g: do we need a class for reading data or > > just a method and how we classify it as a Controller, or a > > Model? View, should we create a View class or a method if we > > will have 3 ways viewing the text. > > > > Scenario 2: Using MVC to display data from a database or multi-database > > Purpose: similar to the above > > Goal : similar to the above, assuming that we have a database > > and we need to create a method or a class of connecting > > to a db, read data, find data, delete data, list data, etc. > > Where do we put this utilities in the MVC scheme as? > > Controller? How do we tie this in the program flow? > > > > Sorry if I''m rambling a bit, but the idea is I''m trying to understand > > the inner working of Ruby on Rails, therefore I can better utilize its > > features. > > > > Thanks > > > > _______________________________________________ > > Rails mailing list > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > > -- > Nicholas Van Weerdenburg >-- Nicholas Van Weerdenburg
On Jan 14, 2005, at 9:03 PM, Michael Koziarski wrote:>> I agree that it is bad having the logic in controllers. But I also >> don''t like to put business logic in in the domain model. I try to keep >> the model objects as lightweight as they can be; if I add logic to >> them >> it is usuall for handling relationships between model objects or >> simple >> getter/setter logic. >> >> My approach is this: I move all business logic, the glue that actually >> puts model objects together to make sense as a whole, in a Service >> Layer. Personally I think this is a much cleaner design because it >> doesn''t pollute the domain model with application logic. >> >> http://www.martinfowler.com/eaaCatalog/serviceLayer.html > > I can quote Fowler too ;). What you''re describing is an anemic domain > model, and the style of programming is quite common in java (IOC > containers especially). > > http://www.martinfowler.com/bliki/AnemicDomainModel.html > > "In general, the more behavior you find in the services, the more > likely you are to be robbing yourself of the benefits of a domain > model. If all your logic is in services, you''ve robbed yourself > blind."In that article he calls himself an ''object bigot''. I guess I''m just a bit more pragmatic than that. I understand what he is saying, but in practice (been using these patterns for a long time) it doesn''t matter much. The end result is a nicely layered application where persistence, business logic and gui logic are all seperate. And easily pluggable (with different implementations or mock objects for example). Also, I quoted that page for the picture, not for Fowler''s highly academic view on software development. Personally I think he has lost touch with reality. Anyway, my applications usually look like this: Backend: Domain Model Objects: User, PhoneNumber These are plain objects. They have NO idea about persistence and do not inherit from any persistence framework. That is handled by the persistence engine transparently. It keeps them dumb. They simply use the language features for relationship mapping to other objects; arrays, maps and object references. Why is this good? I might also want to store a domain object in memory or use it in a GUI using a typical Command pattern. Then I don''t want to have: a) all the extra baggage that for example ActiveRecord''s persistence logic adds to the object and b) don''t want to expose all the business logic to the user of that object. And yes, these are used as ''data records''. I only put logic in there that works with the data in the object or its relations. Like TodoList.add_todo Subscription.expired? or User.encode_password Data Access Objects: UserManager, TodoManager, or simply a global EntityManager These objects contain all the ''base'' operations on the domain model. Things like createUser, disableUser, findUsersByCountryCode, deleteUser. They do not contain application logic. They typically interact with the persistence layer, wether it is contained in an ActiveRecord style or an O/R mapper like TopLink. These are all build on interfaces. UserManager is an interface, UserManagerImpl contains the actual implementation. Application Logic Objects: AddressBookLogic (These are what I confusingly called the ''Service Layer'' in my previous email) Just as the DAOs these are all coded against interfaces. This is great because when I for example want to test if a mailer object works ok then can I simply change the reference from MailerImpl to MailerMockImpl which instead of actually sending email through SMTP will simply log its actions to a file. Plug and play. Great for testing. The IoC container takes care of this, there are NO references to actual implementations in the code, just references to the interfaces. These objects contain all the ''strategies'' of the application. Things like signupUser (unit of work: createUser, createHomepage, createProject, send an email) or createDefaultProject (unit of work: createProject, createDefaultProjectCategories). Service Objects: (Not what Fowler describes) Usually I need to expose Application Logic to an external system through some kind of web service or remoting API. What I do then is build a thin layer in what I call a Service object. These interact directly with the Application Logic. For example say we have a Todo application. In the Application Logic domain i would create a TodoLogic object like this: TodoLogic.createTodo(user, todo_name, todo_priority) TodoLogic.listTodos(user) While this could be wrapped in the TodoService object like this: TodoService.createTodo(username, password, todo_name, todo_priority) TodoService.listTodos(username, password) In this case it simply adds username/password to the service. Frontend: The frontend consists of Controllers, Commands and Validators. Much like rails except that Validators are not directly tied to the domain objects are (form) commands are plain objects. I like to seperate the different concerns.> I''d suggest that transaction demarcation is typically a UI thingMany of my applications don''t have a GUI. Or are simply a GUI on top of a bigger system, a backend that works independent of the web app. So I would say the GUI (the form''s submit action) is one point of transaction demarcation and strategies within an Application Logic object are another place. S.
I think we''re actually closer than you might think. My only concern with your application architecture is the *potential* lack of encapsulation. you have subscription.expired? Given your ''no logic'' constraintI assume it''s just an attribute, or simple method like ''is the status set to EXPIRED''? What happens when the requirement changes from a simple test to something involving associated records or perhaps an external system. Would you then refactor expired? into on of your SubscriptionLogic, SubscriptionService pairs? Then change everywhere that asked subscription.expired to get a service, call the method and get the result? To take your TodoList example, I''d have used: user.list_todos Now, if the users and the todos were both part of my application I''d simply make list_todos return self.todos (managed by AR). However if the todos were controlled by an external system I''d have something like: def list_todos TodoService.get_instance().list_todos(self) end TodoService here is the interface, with pluggable implementations etc. etc. etc. I guess what I''m trying to say is that if you need pluggable this and mockable that, then the services concept is fine, I''d just encapsulate access to them within your domain model so you can vary your UI and your whole services interface independantly. I''m still a little confused by TodoLogic and TodoService in your system, don''t know who calls what. but the general idea is fine with me.> And yes, these are used as ''data records''. I only put logic in there > that works with the data in the object or its relations. Like > TodoList.add_todo Subscription.expired? or User.encode_password > > > > Data Access Objects: UserManager, TodoManager, or simply a global > EntityManager > > These objects contain all the ''base'' operations on the domain model. > Things like createUser, disableUser, findUsersByCountryCode, > deleteUser. They do not contain application logic. They typically > interact with the persistence layer, wether it is contained in an > ActiveRecord style or an O/R mapper like TopLink. > > These are all build on interfaces. UserManager is an interface, > UserManagerImpl contains the actual implementation. > > Application Logic Objects: AddressBookLogic > > (These are what I confusingly called the ''Service Layer'' in my previous > email) > > Just as the DAOs these are all coded against interfaces. This is great > because when I for example want to test if a mailer object works ok > then can I simply change the reference from MailerImpl to > MailerMockImpl which instead of actually sending email through SMTP > will simply log its actions to a file. Plug and play. Great for > testing. The IoC container takes care of this, there are NO references > to actual implementations in the code, just references to the > interfaces. > > These objects contain all the ''strategies'' of the application. Things > like signupUser (unit of work: createUser, createHomepage, > createProject, send an email) or createDefaultProject (unit of work: > createProject, createDefaultProjectCategories). > > Service Objects: > > (Not what Fowler describes) > > Usually I need to expose Application Logic to an external system > through some kind of web service or remoting API. What I do then is > build a thin layer in what I call a Service object. These interact > directly with the Application Logic. > > For example say we have a Todo application. In the Application Logic > domain i would create a TodoLogic object like this: > > TodoLogic.createTodo(user, todo_name, todo_priority) > TodoLogic.listTodos(user) > > While this could be wrapped in the TodoService object like this: > > TodoService.createTodo(username, password, todo_name, todo_priority) > TodoService.listTodos(username, password) > > In this case it simply adds username/password to the service. > > Frontend: > > The frontend consists of Controllers, Commands and Validators. Much > like rails except that Validators are not directly tied to the domain > objects are (form) commands are plain objects. I like to seperate the > different concerns. > > > > I''d suggest that transaction demarcation is typically a UI thing > > Many of my applications don''t have a GUI. Or are simply a GUI on top of > a bigger system, a backend that works independent of the web app. So I > would say the GUI (the form''s submit action) is one point of > transaction demarcation and strategies within an Application Logic > object are another place. > > S. > >-- Cheers Koz