Announcement Announcement Module
Collapse
No announcement yet.
Controller vs Service vs private method on command object. Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Controller vs Service vs private method on command object.

    Which is the better approach?

    1.) have the command object be operated on inside the controller via onSubmit


    2.) Have the command object be operated on by some private method in the controller (separated out)

    3.) Have a interface that operates on the command object.

    Example: BlogService
    would have createBlog(BlogCommand);

    What are the advantagaes and disadvantage of each.

  • #2
    Always clearly separate the tiers and concerns. Your command objects and controllers live in the same tier and are specific to the same web application. Therefore, it is ok and appropriate for your controller to be aware of the command object. That's how Spring MVC works. So, your command object is passed to the controller upon the submission of the view. The task of the controller now is to convert the data from the received command object into a domain-specific object (not presentation-tier-specific) and pass it on to the middle-tier service (again, a non-presentation-tier-specific POJO) that performs the business operation on that data (i.e implements a specific use case.) Therefore, the only correct way to do it is to inject the reference to your business service POJO into your controller, and have the controller redirect the call to it. Never pass Command objects to a business service! Command objects themselves, however, may nest generic business domain objects, but not the other way around.

    To summarize:

    1. The view submits the populated Command object;
    2. The controller converts that app-specific Presentation Tier object into a generic domain object that is recognized by the business service.
    3. The controller invokes the appropriate method on the stored instance of the business service to perform the business operation. You must inject that business service reference into the controller when it is instantiated.
    4. The Controller interprets the result of that business operation according to the application-specific requirements, and redirects to the appropriate view.

    Regarding using private methods... Certainly, in most cases you should be abstracting any functional steps that implement a distinct operation in a separate private method. Subroutines were the first and the best form of abstraction introduced by Fortran (there was such programming language ), and using them is key to elegant, comprehensive, and maintainable software. The short answer, yes, use private methods to abstract any distinct functional steps in your code. Not only it will make it reusable, but even if you don't need to reuse it, it will make your code better structured, more modular, and more readable. Long methods suck. Always.

    HTH,
    Constantine

    Comment


    • #3
      Thank you.
      how about in terms of webflow (for Action).

      I mean i like to call like createBlogs(BlogCommand blogCommand) so I definitely don't like option 1.) in that case.

      Comment


      • #4
        Originally posted by cablepuff View Post
        Thank you.
        how about in terms of webflow (for Action).

        I mean i like to call like createBlogs(BlogCommand blogCommand) so I definitely don't like option 1.) in that case.
        In the case of SWF, you will inject your service POJO into the ActionForm implementation for your view state (or Action if you are invoking the service call from an action state vs. view state transition.) What do you mean by option 1 not being acceptable? Action form is part of your C in the MVC, so passing your Command object to the controller is exactly what you need to do. Now, as I have told you, you must NOT - never - pass your command object to your business service. That means createBlogs(BlogCommand blogCommand) is just wrong. Assuming that you have some "BlogService" [service, middle-tier] class with a "createBlogs()" method, you need also to have some generic Blog-domain specific entity class, like Blog that would store the blog attributes. You read the user input (from the command object that may, in turn contain nested Blog objects, e.g. a List of blog objects) and pass the list of blogs into your service. It may be something as simple as:

        Code in your FormAction:

        Code:
        public class MyFormAction extends FormAction {
            
            private BlogService blogService ;
        
            @Required
            public setBlogService(BlogService svc) {
                 blogService = svc;
            }
        
            // you need to make sure that this method is called on the submit event - in your state definition XML
            public createBlogs(equestContext context) {
                 MyBlogsCommand blogCmd = (MyBlogsCommand) super.getFormObject(context);
                 blogService.createBlogs(blogCmd.getBlogs()); // it may have to return results, you decide...
                 ... do whatever you need here to process the results
        
                 return success(); // this will return the control to your flow executioner
            }
        }
        Hope this is clear. Again, note that we are passing the Domain objects (not specific to your Presentation tier) to the service. your action form serves just as the PT pre- and post-processor. The Business part of creating blogs (possibly, their persisting, etc.) is done by the business service that knows nothing about the presentation tier or any web app, for that matter.
        Last edited by constv; Dec 15th, 2008, 01:11 PM.

        Comment


        • #5
          Originally posted by constv View Post
          So, your command object is passed to the controller upon the submission of the view. The task of the controller now is to convert the data from the received command object into a domain-specific object (not presentation-tier-specific) and pass it on to the middle-tier service (again, a non-presentation-tier-specific POJO) that performs the business operation on that data (i.e implements a specific use case.) ... Never pass Command objects to a business service! Command objects themselves, however, may nest generic business domain objects, but not the other way around.
          I've had a look at the JPetStore example and I see how your comment reflects with the example.

          I was wondering, isn't this a bit of an overkill? The way I look at it now is that one would have a Command object, a Data Transfer Object and an Entity object. The web form data is mapped to a Command object. Then you map the Command object to a Data Transfer object that is then fed through to the Service layer. If it is a Rich Domain design, the DTO would then be fed to the Entity object where the business rules are kept and use the data from the DTO.

          I see from your comment and the JPetStore example that you can encapsulate Business objects within a Command object. To me, I would never refer to a Business object from within the Presentation layer, full stop.

          Wouldn't it be more efficient to, say, have a DTO that the Service layer and the Domain objects/entities can understand and work with. This way, the Domain objects/entities are never visible to the Presentation layer?

          For my next question I'll be open to opinion on this. If the Presentation layer can only talk to the Services using DTO with the example I've provided, is it safe to use the same DTO as a Command object?

          So, as a (high level) example I would implement it as:
          The DTO...
          Code:
          package org.mydomain.example.domain.blog;
          
          public class BlogForm {
          
          private String name; public String getName() {
          return this.name;
          } public void setName(String name) {
          this.name = name;
          }
          }
          The Domain entity...
          Code:
          package org.mydomain.example.domain.Blog
          
          import java.util.Date;
          import org.mydomain.example.dao.blog.BlogDao;
          
          public class Blog {
          
          private BlogDao blogDao;
          ..
          // Other properties can be provided.
          private String name;
          private Date datePosted;
          ..
          public String getName() {
          return this.name;
          }
          public void setName(String name) {
          this.name = name;
          }
          public String getDatePosted() {
          return this.datePosted;
          }
          public void setDatePosted(Date datePosted) {
          this.datePosted = datePosted;
          }
          ..
          public void post(BlogForm blogForm) {
          // A very basic business rule.
          ..
          this.setName(blogForm.getName());
          this.setDatePosted(new Date());
          ..
          this.blogDao.save(this);
          }
          ..
          }
          The Service interface...
          Code:
          package org.mydomain.example.service;
          
          public interface BlogService {
          
          abstract void postBlog(BlogForm blogForm);
          }
          The Service implementation...
          Code:
          package org.mydomain.example.service.standard;
          
          import org.mydomain.example.domain.DomainFactory;
          import org.mydomain.example.domain.blog.Blog;
          import org.mydomain.example.domain.blog.BlogForm;
          import org.mydomain.example.service.BlogService;
          
          
          public class StandardBlogService implements BlogService {
          
          private DomainFactory domainFactory;
          ..
          public void postBlog(BlogForm blogForm) {
          // A very basic business workflow.
          Blog blog = DomainFactory.newBlog();
          ..
          blog.post(blogForm);
          ..
          }
          }
          The controller...
          Code:
          package org.mydomain.example.application;
          
          import org.mydomain.example.domain.blog.BlogForm;
          import org.mydomain.example.service.BlogService;
          import org.springframework.web.servlet.ModelAndView;
          import org.springframework.web.servlet.mvc.SimpleFormController;
          
          public class PostBlogController extends SimpleFormController {
          
          private BlogService blogService;
          ..
          public ModelAndView onSubmit(Object command) {
          ..
          this.blogService.postBlog((BlogForm) command);
          ..
          return new ModelAndView(this.getSuccessView());
          }
          }

          Shah.
          Last edited by shahnawazshahin; Dec 16th, 2008, 06:08 PM.

          Comment


          • #6
            Shah,

            to answer your question, I would have to step back to the root of our other discussions about the basic architectural concepts, the definitions of Domain, services, etc.

            Your concept of Domain Objects differs from mine, or from the authors' of JPetStore, for that matter. I define a functional Domain as a combination of 1) business entities and 2) operations that may be performed over those entities. So far, our views are similar, I think. But when it comes to the implementation, I strongly disagree with the school of thought you seem to belong to. I am not saying it is bad, and I do believe that objects must encapsulate both data and behavior. However, I also believe that being an "object purist" is not necessarily a good thing. Not all functionality that may be applied to a class must live on that class. The most essential concept of the art and craft of software engineering - and the most disregarded, unfortunately - is the concept of de-coupling things that are better off managed separately. Not melting things together allows creating flexible software, it gives you options to use the same things in various contexts without having to repeat yourself, without creating more work and hurdles for yourself. "Object puritanism", or, perhaps "object zealotry", is a dangerous thing.

            There are reasons why the great Edger Dijkstra all but rejected the idea of OO! He once said:

            Object-oriented programming is an exceptionally bad idea which could only have originated in California.


            Now, let's not dismiss his point of view without thinking. Dijkstra spent all his professional life promoting elegance and correctness in programming, and he knew a thing or two about that! His contributions to Computer Science and programming languages are colossal! Every serious programmer absolutely must read Dijkstra's The Humble Programmer article (the ACM Turing Lecture) before they read any modern flavor-of-the-day books on coding practices and design patterns! That may open some people's eyes on what programming should be all about, what testing is really for (not for ensuring the absence of the bugs, if that's what you are tempted to say!) , and many other things...

            Of course, all of us here in this forum are devoted Java programmers, and we appreciate the value of good OO design. I can't speak for Dijkstra and interpret why exactly he personally disliked the idea of OO. Perhaps he saw the danger in the concept that could easily be misinterpreted and taken to the extreme? I'd completely understand that. I definitely disagree with the notion that any object should always be literally self-contained, which implies that it should store the business logic applied to it. I believe (and so do many others) that objects that represent entities must encapsulate their properties/attributes and only the behavior essential to the object's definition - without any business-specific operations that may or may not be applied to that entity. In other words, it is not appropriate to put application-specific business operation into an all-purpose entity. Things like that should be externalized. Therefore, my idea of domain entities is closer to your idea of a DTO or value objects, but not exactly that. I do believe that such entities must implement the kind of behavior without which the entity may not be considered valid and usable. For example, a UsZipCode class may implement zip validation, parsing of the input data, splitting the zip into 5-digit code, 4-digit extension, or representing itself in several different ways: 5-, 9-, or 11-digit code, etc. All of such functionality is essential to defining a US Zip Code concept but it has nothing to do with the world outside the class itself. Nothing in such Zip Code class depends on, or makes assumptions about, how the objects of the class will be used in applications. This is the most essential point that I am trying to make. The entity definitions must be decoupled from any external operations that may be performed on the entity instances. The necessity in such operations (use cases) may come and go, but the domain entity objects will remain what they are - regardless of how they used.

            That is why, I clearly separate the concept of a domain entity, and a domain service. Note that I said "domain service". That's because I see a service as a software module that implements use cases/operations in a particular functional domain. For example, the User service implements user-related use cases and operates on User domain entities. Therefore a DOMAIN concept covers both: entities and operations, but keeps the two separate.

            In your interpretation, the business operations and data are molded together, and then you add a notion of a pure VO/DTO. The advantage of my approach is that I can apply any necessary business logic at any time to my domain entity objects (that carry the data and the encapsulated behavior that only describes the nature of the object, without the business logic). I define the business operations in dedicated services that implement use cases. I can add or remove service operations, but the Domain Object model remains the same. I don't need a separate layer of DTOs, and, most importantly, it is absolutely valid to expose the domain entity objects to the presentation tier (controllers/presenters.) In fact, that is how it should be! And that's what you saw in JPetStore. For example, if you decide that your application needs to use a notion of a User with some of the user-management functionality, you add the User component (e.g. user.jar) as a dependency for your application. Your front-end actions/controllers are aware of the User class and other entity classes defined in that component. They are also aware of the UserService (or UserManager) class that implements some user management functionality. You have no problem injecting that manager instance into your front-end controller, so why would you object the Controller being exposed to the entity classes that are also defined by the same User component? (Remember, in other our discussions I explained how to package classes by functionality, not by type; if yo do that you will always end up with a single independent module that defines both the service API and entity objects.)

            So, there you have it. The Controller receives the application-specific form/command object and maps the data to the domain entity that is recognized by the service (manager), and makes the call to the business method on the service to execute the business operation. Very simple. No additional DTOs, no "gateways". It's nothing new. It's just all about separating things and responsibilities that do not necessarily belong together. It is ok to have a "manager/service" object vs. stuffing everything into a "domain [entity] object." Once you wire something in, you are stuck with that. You should never make assumptions about what operations will and should be performed on an object. A desk is a desk. You can't force everyone to use it in the same way. Some people use desks for work, for writing, for reading, some folks eat at their desks, some might want to do things you won't imagine... None of those behaviors have anything to do with the concept of a desk itself, even though they are often applied to desks... You get my point, right?

            Good discussions.

            Comment


            • #7
              .. and a lengthy discussion at that. Excellent feedback constv!

              I used to code in the similar fashion in that the behaviour and domain objects are separate. It certainly was easier to design with as it is a common design approach, and many examples are provided (even today) using this design.

              So if I had to redesign the example I've provided I would create a BlogManager class where the behaviour is implemented. This leaves the Blog object entity plain as vanilla, with attributes and properties. I'd still keep a separate Service implementation as its main purpose is to encapsulate the business rules and should be kept thin. This is a commonly used design and you'll find that it is adopted within Fortune 500 companies and it is classed as an Anemic Domain Model. But one day found out the hard way that this design an anti-pattern.

              There are so many references available that talk about the Anaemic Domain Model:
              Martin Fowler talks about it http://martinfowler.com/bliki/AnemicDomainModel.html. It strongly encourages that state and behaviour should be at the Domain layer. It does emphasise that the Anaemic Doamin Model is commonly used, however.

              From the Substance of Code, there is a blog item that talks about 'From Anemic to Rich Domain Model' and shows the differences and its opinion between the two.

              There is an item on Wikipedia that talks about Anemic Domain Model (http://en.wikipedia.org/wiki/Anemic_Domain_Model) and describes the benefits and liabilities of using this design.

              From the Spring reference document look up section 6.8.1., which talks about 'Using AspectJ to dependency inject domain object with Spring' (http://static.springframework.org/sp...atconfigurable).
              So there is certainly a demand for Rich Domain Model and already there are designs and approaches that help achieve this.


              Personally I feel that there are a few (yet very crucial) differences between Anemic and Rich Domain Model. I took the time in understanding how to transition from Anemic to Rich and once I nailed it actually made a lot more sense.

              I've worked on a number of projects where I initially used the Anemic Model and then later used the Rich Model. I must say that using Rich Domain Model is actually quite good, and it is easier to design with UML.


              To summarise, do I currently accept Anemic Domain Model? Of course! Even if the Anemic Domain Model is an anti-pattern, one cannot ignore that it is still commonly used design. So I do accept both designs, but my current preference is the Rich Domain Model.

              Thanks for providing the link to Dijkstra's article.


              Shah.
              Last edited by shahnawazshahin; Dec 18th, 2008, 12:01 PM.

              Comment


              • #8
                Shah,
                thanks for the reply! If you noticed, my approach is somewhere in between. I have tried to underline the point that entity objects must have behavior (I never said that they should be plain vanilla data beans.) However, my point is that the behavior that belongs on the object should be the kind that unequivocally defines the entity. I do not believe that you should put any possible behavior you may think of into the object itself. Your objects must be as generic and reusable as possible. As I have said, I want my entities stay the same regardless of the use cases they may participate in - now or in the future. The ease and clarity of the design, implementation, and future maintenance is much more important to me than following some flavor-of-the-day pattern that is considered the right one by some "purist" but makes my architecture rigid and less flexible. Yes, services and managers add some procedural aspect to the overall architecture. But you can't - and there is no need to - eliminate that from any architecture. If it was good for Dijkstra, it's good for me. So, I prefer a reasonable mix - for the sake of clarity, flexibility, maintenability, and efficiency. Which behavior belongs in the entity, and which belongs in a manager object is always a matter of the specifics of the entity in question.

                P.S. Now, perhaps we should stop using the words like "manager" that have a very "procedural" undertone, and simply say that you separate the concepts of the entity and business objects. An entity is what I have described before, the business object is an object that abstracts the specific business behavior that may include manipulating some entity objects. End of the argument. Everything is objects. We just de-coupled the behavior that should be hard-wired from the behavior that is subject to change and depends on use cases, environment, etc, and, most importantly, may or may not be needed. The bottom line - no matter what anyone says - there is always a clear difference between a subject (any subject) and things that can be done with that subject. It would be insane to argue with this simple fact. So why, oh why, would anyone think of combining the two into a single monolithic concept in the software world? That's just not right...
                Last edited by constv; Dec 18th, 2008, 12:21 PM.

                Comment


                • #9
                  Thanks for the feedback constv. This has been an interesting discussion.

                  And certainly this will keep me on my toes. I'll be looking again into this design concept to get a ful understanding and the benefit it provides.

                  I guess finding the right balance that one feels comfortable with is what counts. As long as the design one proposes addresses the problems found in developing software and is reasonable I personally say that it is acceptable.

                  I can see there will be slight variances on designs between solutions and this makes it all exciting to discover new techniques along the way.

                  Many thanks again constv for this discussion. I'm sure this won't be the last of our discussions.


                  Shah.

                  Comment


                  • #10
                    thanks for this awesome discussion.

                    btw should submit values be inside the command object. (this count as user inputted value right).

                    Comment


                    • #11
                      Hi constv,

                      this time I completely on your site - your put my architectural/programming paradigm in the words much better then I can do.

                      But I still disagree with you concerning Dijkstra - he was awesome scientist but none of the software developer and all his words have to be taken with a (giant) grain of salt as far as they deal with something aside algorithms.

                      Regards,
                      Oleksandr

                      Originally posted by constv View Post
                      Shah,

                      to answer your question, I would have to step back to the root of our other discussions about the basic architectural concepts, the definitions of Domain, services, etc.

                      Your concept of Domain Objects differs from mine, or from the authors' of JPetStore, for that matter. I define a functional Domain as a combination of 1) business entities and 2) operations that may be performed over those entities. So far, our views are similar, I think. But when it comes to the implementation, I strongly disagree with the school of thought you seem to belong to. I am not saying it is bad, and I do believe that objects must encapsulate both data and behavior. However, I also believe that being an "object purist" is not necessarily a good thing. Not all functionality that may be applied to a class must live on that class. The most essential concept of the art and craft of software engineering - and the most disregarded, unfortunately - is the concept of de-coupling things that are better off managed separately. Not melting things together allows creating flexible software, it gives you options to use the same things in various contexts without having to repeat yourself, without creating more work and hurdles for yourself. "Object puritanism", or, perhaps "object zealotry", is a dangerous thing.

                      There are reasons why the great Edger Dijkstra all but rejected the idea of OO! He once said:




                      Now, let's not dismiss his point of view without thinking. Dijkstra spent all his professional life promoting elegance and correctness in programming, and he knew a thing or two about that! His contributions to Computer Science and programming languages are colossal! Every serious programmer absolutely must read Dijkstra's The Humble Programmer article (the ACM Turing Lecture) before they read any modern flavor-of-the-day books on coding practices and design patterns! That may open some people's eyes on what programming should be all about, what testing is really for (not for ensuring the absence of the bugs, if that's what you are tempted to say!) , and many other things...

                      Of course, all of us here in this forum are devoted Java programmers, and we appreciate the value of good OO design. I can't speak for Dijkstra and interpret why exactly he personally disliked the idea of OO. Perhaps he saw the danger in the concept that could easily be misinterpreted and taken to the extreme? I'd completely understand that. I definitely disagree with the notion that any object should always be literally self-contained, which implies that it should store the business logic applied to it. I believe (and so do many others) that objects that represent entities must encapsulate their properties/attributes and only the behavior essential to the object's definition - without any business-specific operations that may or may not be applied to that entity. In other words, it is not appropriate to put application-specific business operation into an all-purpose entity. Things like that should be externalized. Therefore, my idea of domain entities is closer to your idea of a DTO or value objects, but not exactly that. I do believe that such entities must implement the kind of behavior without which the entity may not be considered valid and usable. For example, a UsZipCode class may implement zip validation, parsing of the input data, splitting the zip into 5-digit code, 4-digit extension, or representing itself in several different ways: 5-, 9-, or 11-digit code, etc. All of such functionality is essential to defining a US Zip Code concept but it has nothing to do with the world outside the class itself. Nothing in such Zip Code class depends on, or makes assumptions about, how the objects of the class will be used in applications. This is the most essential point that I am trying to make. The entity definitions must be decoupled from any external operations that may be performed on the entity instances. The necessity in such operations (use cases) may come and go, but the domain entity objects will remain what they are - regardless of how they used.

                      That is why, I clearly separate the concept of a domain entity, and a domain service. Note that I said "domain service". That's because I see a service as a software module that implements use cases/operations in a particular functional domain. For example, the User service implements user-related use cases and operates on User domain entities. Therefore a DOMAIN concept covers both: entities and operations, but keeps the two separate.

                      In your interpretation, the business operations and data are molded together, and then you add a notion of a pure VO/DTO. The advantage of my approach is that I can apply any necessary business logic at any time to my domain entity objects (that carry the data and the encapsulated behavior that only describes the nature of the object, without the business logic). I define the business operations in dedicated services that implement use cases. I can add or remove service operations, but the Domain Object model remains the same. I don't need a separate layer of DTOs, and, most importantly, it is absolutely valid to expose the domain entity objects to the presentation tier (controllers/presenters.) In fact, that is how it should be! And that's what you saw in JPetStore. For example, if you decide that your application needs to use a notion of a User with some of the user-management functionality, you add the User component (e.g. user.jar) as a dependency for your application. Your front-end actions/controllers are aware of the User class and other entity classes defined in that component. They are also aware of the UserService (or UserManager) class that implements some user management functionality. You have no problem injecting that manager instance into your front-end controller, so why would you object the Controller being exposed to the entity classes that are also defined by the same User component? (Remember, in other our discussions I explained how to package classes by functionality, not by type; if yo do that you will always end up with a single independent module that defines both the service API and entity objects.)

                      So, there you have it. The Controller receives the application-specific form/command object and maps the data to the domain entity that is recognized by the service (manager), and makes the call to the business method on the service to execute the business operation. Very simple. No additional DTOs, no "gateways". It's nothing new. It's just all about separating things and responsibilities that do not necessarily belong together. It is ok to have a "manager/service" object vs. stuffing everything into a "domain [entity] object." Once you wire something in, you are stuck with that. You should never make assumptions about what operations will and should be performed on an object. A desk is a desk. You can't force everyone to use it in the same way. Some people use desks for work, for writing, for reading, some folks eat at their desks, some might want to do things you won't imagine... None of those behaviors have anything to do with the concept of a desk itself, even though they are often applied to desks... You get my point, right?

                      Good discussions.

                      Comment


                      • #12
                        Oleksandr,

                        I appreciate your posts. I think you may be taking Dijkstra's comments too literally. I agree with your point that requiring a mathematical proof of correctness for each and every piece of code is unrealistic, and I don't think that it was what Dijkstra advocated. The essence of Dijkstra's "Humble Programmer", and many other EWDs and interviews, was, specifically, the call for elegance and intellectual manageability of programs. Dijkstra advocated and encouraged writing software where it would be possible to mentally process each individual piece - even before it is completed in the form of code. Now, if you successfully split and organize a complex problem into an elegant set of simple mentally-manageable sub-tasks, the correctness of the solution might become obvious without a mathematical proof. Such proof would still be a requirement for critical algorithms, obviously, but not for programming web sites that sell pets, etc.

                        Yes, Dijkstra's vision of a software developer was a far cry from what it means to be a SD today. The vast majority of SDs we see today have no Computer Science background - at all. Many SEs - and architects - I meet on my projects approach software development as an occupation where they are simply expected to use certain tools and follow a cookbook of some flavor-of-the-day(!) recipes. Instead of trying to understand the essential algorithms, data structures, the basics of the theory of computation, state machines, work-flows, etc. - all the essentials that could tremendously help one in envisioning and designing software correctly, they start by studying technologies! That is why we see scores of people who can talk for hours about things like JBoss, Seam, Struts, Hibernate, JMS, Spring (w/o necessarily understanding the philosophy and motivations behind this great framework), you name it... But they can't write code, period. They can name any pattern out there, but can't design code. It is really sad. And such "developers" write nothing but intellectually unmanageable code that requires months of testing, and endless maintenance. There are still very good SEs out there, and I have been fortunate to work with quite a few of them, who do write elegant easy to understand and manage code that, once in production, just works. So, I do believe that elegance and intellectual manageability are possible and should always be the ultimate goal. The sad truth, however, is that an average software developer today is just not capable of achieving that.

                        Here are a couple of my other favorite Dijkstra quotes (hope you don't mind.)

                        “Elegance is not a dispensable luxury but a factor that decides between success and failure. In this connection I gratefully quote from The Concise Oxford Dictionary a definition of "elegant", viz. "ingeniously simple and effective". Amen.”

                        “Elegance has the disadvantage… that hard work is needed to achieve it and a good education to appreciate it.”

                        Amen.

                        Cheers,
                        Constantine

                        Comment


                        • #13
                          Hi Constantine,
                          Originally posted by constv View Post
                          ...I agree with your point that requiring a mathematical proof of correctness for each and every piece of code is unrealistic, and I don't think that it was what Dijkstra advocated.
                          As far as I can remember it was, but I may be wrong as I have read his works about 30 years ago Probably, need to re-read.

                          ... where it would be possible to mentally process each individual piece - even before it is completed in the form of code.
                          Exactly what Dijkstra has done - as far as I know he never, ever wrote a piece of working code

                          Now, if you successfully split and organize a complex problem into an elegant set of simple mentally-manageable sub-tasks, the correctness of the solution might become obvious without a mathematical proof.
                          That's true, KISS is a great principle.

                          Such proof would still be a requirement for critical algorithms, obviously
                          Obviously, not - for 2 reasons
                          1. Such proof may be just impossible (there are a lot of things that cannot be neither proved, nor contradicted)
                          2. If possible, it may much more complicated then algorithm itself and as such more error-prune then algorithm itself. And proof typically is untestable.
                          In such cases other approaches may be viable - e. g. implementing alternative algorithms and obtaining results by "voting".

                          Yes, Dijkstra's vision of a software developer was a far cry from what it means to be a SD today.
                          Sure, as his (purely imaginable) software developer never was intended to be mass-production software developer, rather computer scientist.

                          The vast majority of SDs we see today have no Computer Science background - at all.
                          From my experience the best developers have mathematical background ("pure" mathematic, not computer science).

                          Many SEs - and architects - I meet on my projects approach software development as an occupation where they are simply expected to use certain tools and follow a cookbook of some flavor-of-the-day(!) recipes.
                          For many projects it is more then enough (if they at least try to understand reasoning behind those receipts).

                          Instead of trying to understand the essential algorithms, data structures, the basics of the theory of computation, state machines, work-flows, etc. - all the essentials that could tremendously help one in envisioning and designing software correctly
                          Or, as I have seen much more often, overengineer it tremendously.

                          , they start by studying technologies!
                          Not so bad as far technologies do not become goals in and of themselves.
                          The main reasons behind technologies is elimination of many problems and steps that otherwise need to envisioned, designed and implemented ...
                          But they can't write code, period.
                          Sopme of them. And it has almost nothing to do with background. I became convinced once and again that or a person can write usable code, or not, and any amount of education (save very initial one), experience, ... (name one yourself) can not change it. Able person can become better, really good, excellent ... . Unable is unable, sorry (like in a music, painting, ...) .

                          Kind regards,
                          Oleksandr

                          who do write elegant easy to understand and manage code that, once in production, just works. So, I do believe that elegance and intellectual manageability are possible and should always be the ultimate goal.
                          ...

                          “Elegance has the disadvantage… that hard work is needed to achieve it and a good education to appreciate it.”
                          Creeping elegance—which is related to creeping featurism and second-system effect—is the tendency of programmers to disproportionately emphasize elegance in software at the expense of other requirements such as functionality, shipping schedule, and usability. - from Wikipedia

                          Regards,
                          Oleksandr

                          Comment


                          • #14
                            I swear, Oleksandr, your posts, while very intelligent, in addition to many valuable points, contain some of the most outrageous examples of pure demagogy I have ever seen - no offense. Of course, CS degree doesn't guarantee anything. However the chances that a person who deliberately chose to spend 4-6 years of his/her life to study CS (or math!) might display more interest in learning, understanding, and applying the appropriate knowledge working in that field then someone who became a programmer almost by accident - only because it pays more than delivering pizzas with a degree in history or liberal arts... I have worked with a person who had a Philosophy degree from Yale. He was one of the best I had seen! But he was an exception to the rule...

                            Creeping elegance—which is related to creeping featurism and second-system effect—is the tendency of programmers to disproportionately emphasize elegance in software at the expense of other requirements such as functionality, shipping schedule, and usability. - from Wikipedia
                            Come on... You know better than this... It's just not fair to use something like this as an argument. This is not even serious. This "expert statement" confuses the elegance in software we are discussing with crafty "smart" trickery and so called "optimizations" that, indeed, hurt code readability and usability. That is NO elegance. That is incompetence! The same goes for your comment that people who know too much might over-engineer things... Any kind of over-engineering - to me - indicates a certain degree of incompetence or lack of experience, or, sometimes, even an inferiority complex! Of course knowledge in the wrong hands is dangerous! Who would argue with that? true competence is NOT to over-engineer, and that's what I have been saying all along.

                            My point is that it takes hard work, talent, education, imagination, and creativity to be a good software engineer, to be able to create good software. The last but not least, it requires passion for the craft of Software Engineering. It's not that the idea of elegance and simplicity is a wrong idea. It is very difficult to achieve, yes. That's true, some people just don't have it. You are right on: it's the same with music, or any kind of art. The fact that so many people just don't get it right only proves my point: they are not good software engineers.

                            I also very much agree with your "mass-production software" era comment. Continuing to use the comparison with the music field, this explains why the market is saturated with programmer equivalents of Britney Spears or the likes of her, or even worse...

                            Regarding Dijkstra's proofing comments, here's another quote:

                            "But one should not first make the program and then prove its correctness, because then the requirement of providing the proof would only increase the poor programmer's burden. On the contrary: the programmer should let correctness proof and program grow hand in hand."

                            This - at least to me - has always meant one thing: design so that at any given step you know what exactly you are doing, don't write hundreds of lines of code first and then keep your fingers crossed hoping that it would work. Know that it will work.
                            Last edited by constv; Feb 13th, 2009, 12:05 PM.

                            Comment


                            • #15
                              Originally posted by constv View Post
                              I swear, Oleksandr, your posts, while very intelligent, in addition to many valuable points, contain some of the most outrageous examples of pure demagogy I have ever seen - no offense.
                              Sure they do - on purpose. You may consider it as my hobby.

                              However the chances that a person who deliberately chose to spend 4-6 years of his/her life to study CS (or math!) might display more interest in learning, understanding, and applying the appropriate knowledge working in that field then someone who became a programmer almost by accident - only because it pays more than delivering pizzas with a degree in history or liberal arts... I have worked with a person who had a Philosophy degree from Yale. He was one of the best I had seen! But he was an exception to the rule...
                              The problem is that CS people tend to put way too much attention to the technical and technological aspects of development, micro-tuning of the details and so on - instead on concentrating on problem content. And why have said "among the worst" - good CS peoples are really good, but bat not so good typically are much more stubborn then any other not so good what make them "worst of the worst".

                              I would say that they do not generalize enough. Maths (which I proudly represent) ) typically do not suffer from this kind of problems.

                              Come on... You know better than this... It's just not fair to use something like this as an argument. This is not even serious.
                              Sure, it was not an argument, merely joke (while it is really from wikipedia).
                              The same goes for your comment that people who know too much might over-engineer things...
                              It is quite different things - too know a lot and to be able successfully apply this knowledge. And people with lot of knowledge but not enough experience and/or talent tend to apply the whole knowledge in one shot, making things way too complicated.
                              true competence is NOT to over-engineer, and that's what I have been saying all along.
                              Sure, can not agree more. And understanding and analytical skills are much bigger parts of competence then pure knowledge.
                              My point is that it takes hard work, talent, education, imagination, and creativity to be a good software engineer, to be able to create good software. The last but not least, it requires passion for the craft of Software Engineering.
                              Can not agree more.

                              It's not that the idea of elegance and simplicity is a wrong idea. It is very difficult to achieve, yes.
                              Which effectively makes it useless (or impracticable) for the wast majority of projects - it can be several times and finished with standard approaches in the time needed to find really elegant solution.

                              It has to be reserved for the most challenging projects or even for the most challenging part of those projects according to 20/80 rule.

                              Regarding Dijkstra's proofing comments, here's another quote:

                              "But one should not first make the program and then prove its correctness, because then the requirement of providing the proof would only increase the poor programmer's burden. On the contrary: the programmer should let correctness proof and program grow hand in hand."
                              It does not make it more realistic. To put it straight - "correctness proof" as was understood by Dijkstra in nothing more then pure nonsense - for many reasons bot theoretical and practical. Their discussion deserves not a few words in a post, but a series of articles.
                              But the same strategy applied to the testing may do (and do) wonders.

                              This - at least to me - has always meant one thing: design so that at any given step you know what exactly you are doing, don't write hundreds of lines of code first and then keep your fingers crossed ...
                              It may be not so bad, there is only one problem - you not always (and to put it straight - in commercial SW development almost never) know in advance what exactly you have to achieve. Because requirements and goals are not merely moving, they are flying - in butterfly style.

                              Kind regards,
                              Oleksandr

                              Comment

                              Working...
                              X