Redundant code

There are times that as a coder we end up creating the same code over and over, causing unnecessary lines of code and increasing the complexity and manageability of the program, as a change might be made in one of the several routines, but one might be left behind and that one will bomb and cause an issue, debugging also gets hard as the lines look so similar that finding the issue is next to impossible.

So how can one create modular code and reduce redundancy? Just last week I was in Sydney conducting a CoronaSDK workshop, I guess this is the first ever in Australia. So one of the participants was trying to create an app, now without getting into what he was trying to do, let me talk about the problem that I found in that approach. At the same time given that the participant saw Corona for the first time in their life, so what he was attempting was quite clever, but it can be optimized and that is what I shall dicuss here.

 local block1, block2, block3, block4, block5

local width = display.contentWidth
local height = display.contentHeight

block1 = display.newRect(10,10,50,50)
block1:setFillColor(255,255,255)
block1.x = 10
block1.y = height - block1.height

block2 = display.newRect(10,10,50,50)
block2:setFillColor(255,255,255)
block2.x = 10
block2.y = height - (block1.height * 2)

block3 = display.newRect(10,10,50,50)
block3:setFillColor(255,255,255)
block3.x = 10
block3.y = height - (block1.height*3)

block4 = display.newRect(10,10,50,50)
block4:setFillColor(255,255,255)
block4.x = 10
block4.y = height - (block1.height * 4)

block5 = display.newRect(10,10,50,50)
block5:setFillColor(255,255,255)
block5.x = 10
block5.y = height - (block1.height*5)

Now just looking at that piece of code, one can instantly see that it requires to be modularised to be made re-usable. I will not go into buzz words of patterns, etc I will just say in plain words that it can be made smalled and more efficient and in my opinion this is how.

 local width = display.contentWidth
 local height = display.contentHeight

 local blocks={}
 local blockCount = 5
 local i

 for i=1,blockCount do
  local block = display.newRect(10,10,50,50)
  block:setFillColor(255,255,255)
  block.x = 10
  block.y = height - (block.height * i)
  blocks[i] = block
 end

see how the code is smaller and now you can have as many blocks as you want, it can scale up or down as required.

Then he was wanting to have a transition that would work on each of the blocks in sequence, one after the other. The code looked like

 local function transblock1()
   block1.x = width - block1.width
   trans1 = transition.to(block1, {time=2000, x=-block1.width, onComplete=transblock1})
 end

 local function transblock2()
   block2.x = width - block2.width
   trans2 = transition.to(block2, {time=2000, x=-block2.width, onComplete=transblock2})
 end

 local function transblock3()
   block3.x = width - block3.width
   trans3 = transition.to(block3, {time=2000, x=-block3.width, onComplete=transblock3})
 end

 local function transblock4()
   block4.x = width - block4.width
   trans4 = transition.to(block4, {time=2000, x=-block4.width, onComplete=transblock4})
 end

 local function transblock5()
   block5.x = width - block5.width
   trans5 = transition.to(block5, {time=2000, x=-block5.width, onComplete=transblock5})
 end

Now this seemed like a mishap waiting to happen. The code can be modified to make it modular as

 local object
 local trans

 local function doTransition()
  object.x = width - object.width
  trans = transition.to(object,{time=2000,x=-object.width, onComplete= doTransition})
 end

Thought this might seem a bit strange at first, let me explain what we shall do. I could have added a parameter that we pass to the function called object, but then when we want to have this repeat itself on complete, we are unable to pass the parameter object to the function, so it will give errors. But in this code above, since there is no parameter passed, object is set outside of the code and hence even when it is repeated, the object shall persist and the code will not give errors.

we can call it as follows

 object = blocks[i]  -- I can be the number as per requirement
 doTransition()

then there was the need to stop the transition when the screen was tapped. so the code that was created earlier was as follows
 local function onTapStop(event)
  if level==1 then 
    transition.cancel(trans1)
    transblock2()
  elseif level==2 then 
    transition.cancel(trans2)
    transblock3()
  elseif level==3 then 
    transition.cancel(trans3)
    transblock4()
  elseif level==4 then 
    transition.cancel(trans4)
    transblock5()
  elseif level==5 then 
    transition.cancel(trans5)
  end
    level=level+1
 end

 Runtime:addEventListener("tap",onTapStop)

He was keeping track of what was happening by using a flag that held the number of the block that was transitioning. Now with the way that I have suggested, the modular code would be even simpler and the code would look like

   local function onTapStop(event)
     transition.cancel(trans)
     level=level+1
     if level < blockCount then
       object = blocks[level]
       trans = doTransition()
     end
   end

   Runtime:addEventListener("tap",onTapStop)

I hope that some of you would have learned something from this. It is a better form of development to have modularity in the program. If any code has to be duplicated, it is easier to modularise it so that it provides a consistent experience all across. If you had several of the same code and a change had to be made, and one particular line was left out, it would be a disaster and debugging would be a nightmare as the code would seem to be fine as it looks the same for several lines.

more later,

cheers,

?:)

Comments

Popular Posts