jeudi 21 avril 2016

How to fight the startover effect

When I'm asked to fix a bug or introduce a feature in a project I did not develope I often have this feeling that starting from scratch would safe me a lot of work, pain and effort. Altougth often this obviously is more work and seems like I suffer greatly from nih.
So what are ways you fight this urge and focus on the project or enable yourself to morph the project bit by bit to something you like more while fixing bugs or introducing features?

To make some points about me:

  • I'm a fairly good programmer
  • I would consider myself a python programmer, meaning I try to follow the Zen of python
  • I don't really like big abstraction (more in the example below)
  • Obviously sometimes I have that problem with my own code.

To make some points about the projects I talk about:

  • Lately most of them are based on php but might be any language
  • Propably coded by someone who never really coded big projects or in teams
  • Most often with a lot of classes and pseudo-abstraction (more below)
  • Most likely without comments at all
  • Bad named variables, classes and functions
  • A lot of redundancy for instance a lot of style="border:1px solid black" or the same javascript function with different names in every htm file, or classes that will call each other in turns
  • Huge switch statements over like a couple of hundreds of lines
  • Sometimes build atop of librarys that are deprecated or just way to big for serving a very small feature set.
  • Huge Codebase without really splitting up the codes in different files
  • Weird globals
  • Dead code in weird places (like in the switch statements)

How I try to solve it:

Lately if I have to fix something I will do so and after finding out what happens and beeing anoyed by it, I will put a lot of #TODOs in there and fix the initial problem.
Often with this method I use the predefined functions or classes that by their name should do something completely different, making the project more horrific.

The example

I told you that I have a problem with big abstraction, by this I mean the following thing. Lately I was asked to put an invite function into a webpage. Surely enought there was an invite function but with some code missing, so I tried to use the codebase and after some hours I noticed that everything was intertwined with the lost-password recovery. So I can't really mess with that code a lot without removing that password reset.
The code basically worked like this:

  • if an admin creates a token for the invite function he will create a token class and safe the token to the database by using an offer class
  • the offer class took the token object and safed the token itself to the db and then called its notify function to inform the invited user.
  • Then the user clicks on the invite link with token, and creates the token object again to check if all is valid. Obviously you also have to create an offer object now just to clarify the matter
  • After he put in his data by using the predefined data from the admin read via a register class that returns a kind of user class object, he is send to validate his token again with the token/offer class
  • Then he will create a registerinvite class that is basically the register class with one additional function the registerinvite function, that takes an offer object, a token object and the data submitted by the user again checks it, and then sends the data to the initial register class that does the rest then.
  • On error the registerinvite function returns false and will set the $_SESSION['e'] field to some language specific error string, that will indicate the code that registerinvite has failed and this string should appear.
  • This is done by reloading the page with header("Location: .") reading $_SESSION['e'] into $e and then unsetting $_SESSION['e'].
  • After this the token/offer check is done yet again but stopped before trying to registerinvite because there is no post data. And then the error is shown in the form.
  • To mess things up totally all the functions involved except for the registerinvite-step are used in the password reset thing. Even thought offer does indicate something else.

Conclusion

  • Somebody learned OOP but didn't learn to use it where it is needed
  • Everything is intertwined, so it might break if I change it in the slighest
  • There is a straightforward implementation using less functions and classes
  • it is hard to understand the control flow
  • some globals serve a weird purpose
  • and what not

I'm sorry that I took so much text to clarify the issue while not really clarifying anything. This is a soft question, so every help is appriciated.

Aucun commentaire:

Enregistrer un commentaire