Do you really need different ways for doing the same?

Published on and tagged with software engineering

If you develop an application/library/framework it is sometimes tempting to provide different ways to solve a particular “problem”. In CakePHP you can, for example, create a submit button with:

echo $form->submit('Save');

or with:

echo $form->end('Save');

The first snippet shows the generic solution to create a submit button, the second is a shortcut to create such a button at the end of a form (plus it closes the form).

At first glance this looks pretty nice. But if you think about it, you will see there is quite a price to pay: you have to write and maintain more code, you have more to document and to teach the users, and the users have more to learn…

Sometimes it is worth to pay this price, sometimes not. It’s your decision whether you are willing to pay the price.

16 comments baked

  • Me

    I understand what you are saying mostly, but could you elaborate on why using the end function would cause you to have to maintain more code, more documentation and more the users have to learn?

    Seems like a simple code choice to me

  • Nanoman

    I don’t really what the problem is and find this post kinda pointless. It is just a convenience way, as many things in CakePHP are.

    If I think about it, I don’t have to write and maintain more code, I don’t have to document more and why should the users have more to learn ?!?

    And which price? :-)

    Anyway, I like your blog very much, but as said, this is just pointless taunting the core team.

  • Martin Bavio

    daniel, I really love your blog. It has teached me a lot in the first stage of learning cake. However, I think this post is pointless, and it seems like a calling for war against the core. In some post, I noticed that you seem a litle recentful to them… Is there any issue that i´m not aware of?

    Martin B

  • Jeremy

    When I read it, I thought he meant more towards the cakephp developers point of view, not people using cakephp, we’re the users that they have teach us more. or maybe i’m just far off

  • Tim Daldini

    I always use the most intuitive approach, that is, always using submit in such a case because it does exactly what it says. That way it is more understandable for others, or for yourself after not having used the framework for a while trying to remember some convenient inner workings while getting back on track. You have to “know” end() works in that specific way when it is called with one argument.

    Also, when you later decide to add another submit button in the same form you would end up replacing the end() call anyway by two submitbuttons, so I consider always using submit to be the most universal solution.

    But in this case, I think having the choice to do both is not a bad thing.

  • cakebaker

    @all: Thanks for your comments!

    @Me, Nanoman, Martin, Jeremy: Well, this article is written from the point of view of the developer of the methods (submit() and end() in the example I used), not from the (framework) user’s point of view.

    If I am the developer of those methods, I have to write tests for both methods to verify that both methods generate a submit button. And I also have to describe it twice in the API doc blocks of the respective methods. And I probably have to mention both ways in the manual.

    And as a user I have to learn both ways for creating submit buttons, as you will see both ways used in the wild.

    The example I used was from the framework level, but you could also take an example from the application level, e.g. a login form which allows you to use either an OpenID or a username/password combination to login. Maybe this would have been a better example?

    Anyway, I hope it is now more clear what I tried to say with this article ;-)

    @Tim: Yes, the submit() method is more readable than end() with one argument. Providing choices is not bad per se, but you (as the provider of the choices) have to be aware that you don’t get them for free.

  • Neil Crookes

    I think $form->end() also adds additional code if you are using the Security component.

  • CakePHP & DIEVOLUTION Blog » Blog Archiv » Kurztipp: Aufpassen bei Ajax-Forms

    […] ohne Werte per Ajax vom Server geschickt wird. Am besten nutzt ihr hier den Formhelper wie ihn cakebaker beschreibt, dass spart sogar noch eine […]

  • MN

    Hi there,
    I know that here is not an exact place to ask my question but I have tried to use Model::save function to save a new value for one field in my table and found out that cake uses an INSERT sql command for saving the data resulting in a new row to be added every time! is this my problem or I haven’t seen a role in using that function?

  • Jeff Loiselle

    Daniel, you pose the question, “Do you really need different ways for doing the same?”. Well, let’s use our noggins!

    PHP gives you all of the tools you need to build a web site. Why do you need a framework at all? SQL is far more flexible than Cake’s ORM layer in many cases, so why build one! Hell, why do you even need file_get_contents() when you can fopen() your way to fame and fortune. Why do you need high level languages at all if one can sit down with a hot cup of joe and crank out some ASM.

    Technically, all these things don’t really do the same thing do they?

    Some things are based on convenience and there’s hardly a price to pay to support the two methods of syntactical sugar you mention. The methods don’t do the same thing. Period.

    Take a deep breath and talk about something more important.

  • Tim Daldini

    If you want Model::save to do a UPDATE instead of an INSERT you should make sure the value of the primary key is in the array you are passing the the save method.

    For example, if you are trying to update the ‘name’ field from ‘George’ to ‘John’ the array you pass to model::save should contain a ‘name’ key with the value of John AND an ‘id’ key with the value that corresponds to the record you are trying to update.

  • Beth

    I’m not worried about who’s right or wrong. Daniel at least posed the question and squeezed out some potential rationale for their existence @Neil. The heart of the matter is WHY button option exists in both methods and WHEN to use $form->end(‘Button’) vs $form->submit!! For now, I’ll stick with what I know.

    I look at it this way, everyone knows that $uses and $html->link are slow/resource hogs, yet it’s preached, tutorialized, blogged, documented like the gospel because of the “automagic”. Either you take the red pill or the blue, it’s up to you. But when you wake up to sheeit performance who’s fault is that? You!

    I choose to use the form helper to display error messages because I want to be able to internationalize the messages even though the downside is displaying error message below a field is BAD usability. BTW, I have multiple rules per field and form->error doesn’t work without more work which I don’t have time to hack. I also don’t believe in hard coding messages in the model.

    IMHO, debate is good within a community. Either everyone wants a good product or their egos stroked. Look at Rails if you think everything is so rosy –

    Daniel has at least stuck with Cake unlike a lot of others who have gone DOA. I won’t name names. Cake really needs a community leader such as Fabien from Symfony.

    Can anyone name 10 cake blogs that are still providing relevant information/examples? And I’m not talking about regurgitating the same old stuff for every new release of cake, i.e. Blog Tutorial for Cake x.x.x.

    Ah, I feel clean again ;)

  • ajmacaro

    Hey, i didnt know end() has a parameter. :)

    When you see things useless, then it is useless. Think positive,
    what you just read doesnt waste any of your precious time.
    If my boss ask me why there are two functions. Then i have some
    answer for him. “Why dont you read cakebaker blog. and read the

    Sometimes i question myself. Why people have to use “this and that”, if he can use “this and that”? Then i realize, simple because some prefered to use “this” rather than “that”.

  • cakebaker

    @all: Thanks for your comments!

    @Neil: Yes, $form->end() adds a hidden field if you use the Security component.

    @MN: An addition to Tim’s explanation (@Tim: thanks!): If you have only one field to update, you could also use the following code:

    $this->YourModel->id = $yourID;
    $this->YourModel->saveField('fieldname', 'value');

    @Jeff: Well, I think you miss the point. My point is that you should think twice before you add the second/third/… way for doing something you already implemented in your software. In principle it is about DRY (don’t repeat yourself) at the feature/documentation level.

    It’s possible that the example I have chosen is not the best example, as the end() method does a bit more than the submit() method. But think about the scenario of finding all users with a certain name. How many different ways are there to accomplish this task?

    @Beth: Yes, I agree with you that it is good to have debates in the community.

    @ajmacaro: Cool to hear you learned something from this article :)

  • Matt Huggins

    @Beth – You said “The heart of the matter is WHY button option exists in both methods and WHEN to use $form->end(‘Button’) vs $form->submit!!”

    I believe the submit() function includes a second array parameter that allows you to provide additional attributes (such as onclick, style, css class, etc.) much like other input functions within the FormHelper. The end() function does not provide this option, it simply creates a very basic submit button with the caption provided.

  • cakebaker

    @Matt: You can also provide options for the end() method, see the API.

© daniel hofstetter. Licensed under a Creative Commons License