Horrible code coping - 4 ... ideas.

by Jesse 8. February 2010 20:51

I've heard about those projects people end up on and I'm sure you've heard of them too. Everything is done in the most complicated way known to man never to be understood again.  There are odd debugging like statements with logic in them that might be useful ... strange, undescriptive (cryptic?) variable names to which you have no idea what they might do and don't forget your god classes -- those are a must!  So before we go down this pile of atrocities against the human race, let's look at some examples.  Sadly, these are real world examples.

                If thisRow("FormField").ToString().Trim() = "check12a" Then
                    strValue = strValue
                End If

                If thisRow("ExhibitTest").ToString() <> "" Then bDoExhibit = CType(RetrieveValue(thisRow("ExhibitTest").ToString(), "E", "", docInput, xpathNav), Boolean)

Yes, I have seen the strValue = strValue in the real world.  It's sad and seriously calls into question "WHAT WERE YOU THINKING?".  I can't ask that, those people are long gone.  There's no documentation, the code isn't very readable and to boot -- the database takes a while to save stuff (so checking on saved items might take 2 seconds or 15+).  So as a better developer, what do you do?

1. Ask for some refactoring time for readability.  This won't gain the customer anything except readability.  It will get you familiar with the system and if you've done you're homework (cough unit tests) nothing will change.  Yes, I said it will gain them nothing because to the customer, northing has changed.  This isn't an easy task, at all.  It can take a day or a few weeks depending on how bad it is.  So find a nasty method and start pulling it into multiple methods and make it readable ... this also gives you a place later on to replace stuff and make good recommendations later.

2. Look for ways to make it better, quickly.  Look for quick wins.  If there's simple fixes like text/data related outputs, look for those.  This could also backfire (in my case I made a mistake, it uncovered the worst of the worst and has cost me 24 hours of work) but set a time limit of a 15 to 30 minutes.  This is more to demonstrate that just maybe you know what you're doing.  A pile of little bug fixes will probably look better than one big one ... unless they said they want one fixed first.  It's your job as a developer to let them know it might be better to fix the little ones, just for your own sanity.

3. Be patient.  When dealing with truly terrible, amateur (hobbyist?) written system, frustration will be expected.  Try not to think of the system as someone you want to beat with a coal shovel because they might deserve it and should not have EVER been given a keyboard, much less the OK to develop anything, but think of it as a bad child that needs a little (ok, a LOT) of discipline.  Be that discipline, be that foundation and lead it the enlightened path.  It might take you 3 months plus to get a good feel for a system so don't expect to know it in a week.  Remember, that's why you're there.

4. Take the high road.  You know it sucks, but don't go smashing it with the hulk gloves.  Why?  Someone within earshot might have actually worked on it.  Worse, they could be proud of it.  Worse still, the client personally worked on it ... and is proud of it.  If asked "how bad is it" give them an honest answer, but not surrounded in massive amounts of anger, frustration, etc and blame thyself.  "I don't quite understand how the system is setup and I'm not sure what patterns are used" would be a good answer, whereas "dude, this is the biggest pile of steaming failure I've ever seen, who the f wrote this?" isn't as elegant.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Subsonic, Oracle, and fighting the fail

by Jesse 8. February 2010 20:25

If you've seen my twitter feed lately (if you haven't, I don't blame you), I've been complaining a LOT about datasets, so I went looking to an old friend, subsonic.  Why subsonic?  Because it works.  It works well.  It works with just about every database I've EVER come across.  In my opinion, its a true abstraction layer between data and service to which it fits nicely in between because it works with so much stuff.

As of late, I've been taking Jon's suggestion of highly-specialized interfaces -- GetService, UpdateService, DeleteService and CreateService to make up a one stop shop to make this work.  I know he didn't invent this idea, but he brought it to my attention in a very indirect way.  Anyway, I've found this to be a great idea, but it's amazingly difficult to imbue on certain data layers, such as with datasets.  I WAS able to use a IGetService for it, as such...

public class GetService<T> : IGetService<T> where T : class, IObjectToEntity, IDataTableEntity
{
    
private DataTable _table;
    
private SuperAdapter _adapter;
    
private OracleDataAdapter _dbAdapter;
    
private IQueryable<T> _entityList;

     public GetService(DataTable table)
     {
          _table = table;
          _adapter =
new SuperAdapter();
          _dbAdapter = _adapter.AdapterFactory(_table.TableName);
          _dbAdapter.Fill(_table);
          _entityList = _table.Rows.ToEntityListOf<T>().AsQueryable();
     }

}

With an extension method of .ToEntityListOf<T>, this became an awesome way to convert the horrid datasets into a more manageable object to get things like, oh I don't know, IDs and other useful data out, easily.   Each entity was given a constructor that parsed the datarow into the object ... nice hu?  Unfortunately, this is where this ended.  It was near-impossible (not worth the time) to get the Delete/Create/Update to work so I abandoned it since at LEAST I was able to see the base data.  As heavy as this operation was/is, it gave me a bit more control over the data.

Then I had to clean up the data in the database... something along the lines of 2000 records scattered all over the place -- 4 tables, 3 lookup tables namely.  I went looking for subsonic.  I asked the same question "can I use the individual get/update/etc services?" and you CAN.

My typical GetObjectService does the usuals.  Gets by Id, Gets by an expression or just gets everything.  That's not hard.  What CAN be hard is figuring out how to get whatever data layer you're speaking though, to do what you want, how you want it.  I'm using subsonic 2, so there's no linq ... that doesn't mean it can't work with it.  "Well, you could use the Subsonic.Query" and you'd be right, but I don't want to use anything more than absolutely necessary, I'm driving for core simplicity.  This can make things a bit ugly but not less maintainable.  Digging into subsonic a little, a lot of things worked around the ActiveRecord object and gave me a sense of where to start... and that's where it ended -- take this for example, my get by expression ...

public IQueryable<TEntity> Get(System.Linq.Expressions.Expression<Func<TEntity, bool>> expression)
{
    
var collection = new TCollection();
     collection.LoadAndCloseReader(
ActiveRecord<TEntity>.FetchAll());
    
return collection.AsQueryable().Where(expression);
}

Yes that last line is kinda ugly ... but it gets the job done and is not hard to figure out.  EXACTLY what I'm looking for.  If I move in another datalayer, what are the chances the manipulation would be the same in some way?  Pretty high, so I'll take it.

Ok, so far so good, but so what?  Gotta test that right?  Yes, and that's a bit easier to do than you might think.  Using Moq, I came up with a "FakeGetObjectFactory" ... looks like this.

private Mock<IGetObjectService<TEntity>> FakeGetServiceFactory<TEntity>(List<TEntity> fakeList) where TEntity : ActiveRecord<TEntity>, new()
{
    
var mockGet = new Mock<IGetObjectService<TEntity>>();
     mockGet.Setup(mock => mock.GetAll()).Returns(fakeList);
    
mockGet.Setup(mock => mock.Get(It.IsAny<int>())).Returns((int i) => fakeList.Find(fake => fake.GetPrimaryKeyValue().ToString() == i.ToString()));
     mockGet.Setup(mock => mock.Get(
It.IsAny<Expression<Func<TEntity, bool>>>())).Returns((Expression<Func<TEntity, bool>> expression) => fakeList.AsQueryable().Where(expression));

    
return mockGet;
}

In english, the "It.IsAny<>" says exactly that -- if its any int, do the following stuff.  Using this is quite easy, since you're tossing in a List<TEntity> (an in-mem repository if you will) as a parameter ...

     _mockFakeGetService = FakeGetServiceFactory(_fakeList);
     _getFakeListService = _mockFakeGetService.Object;

Done and done!  Now my _getFakeListService acts like it does everywhere else AND my code is testable now!  The bigger bonus is later on, if the client decides to move it to sql (99.999999% likely), they can, and they have a place to do this.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , , , ,

Opinion : What happens when failure is not only an option, but assumed?

by Jesse 31. January 2010 10:42

I've been on a few projects recently where "no one wants it", "no one wants a part of it", "it's terrible", "oh you're on that ... good luck" and every type of don't-want-it you can imagine.  The type of project you -really- want to ask the people that were there before and ask them just WHY.  The client knows it, you know it going in but you do it anyway.  Then something totally unexpected happens... it doesn't fail.  It may even become an amazing success, and even more oddly, it usually does.

So why don't they fail?

Since I've been off a particularly challenging project, I've had time to not only be on another failure assumed project, but think about what happened.  Interestingly, a video game summed it up.  There's an intro in modern warfare 2 that talks about the characters being on a suicide mission.  They know they're going to die doing this, but there's a bit of liberation, a freedom that occurs when you know something is -going- to end but you get to decide that outcome.  It releases your mind to do things you normally wouldn't consider acceptable, much less possible.  "It's stupid enough it just might work" is a requirement.

This is where the original problem was kept, hidden from view.

I've now sat here for half an hour, writing and rewriting an explanation of a blend of contained creativity and fear of failure seem to truly cripple projects.  I can't come up with concrete examples nor even theoretical examples -- yet somehow the argument still seems valid.  I'm not sure if the expectations need to be adjusted, such as on style.  Who says "this is the way yee shall render a grid!" ... there's reasons why cars, homes, businesses all look different.  When people are told "we have no idea how this is going to work, but we want to you to <accomplish something>".  Maybe a focus needs to be on the resulting end goal instead of all the problems on the way?

To return back to my own promise of posting "how long did this take" -- this post took 2 hours and one review by someone not in the tech world ... at all.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

PDF form ORM becomes reality

by Jesse 23. December 2009 22:31

I had threatened it here, and last night I released the code for the pdf-orm concept I had been working on, messing with, half-heartedly test and using out to  codeplex.  If you get a chance, go check it out.  It's simple yet effective, and hopefully you could find it useful.  Anyway, you can find it at http://pdform.codeplex.com !

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

Tech Night - talkin' bout production deployments

by Jesse 3. December 2009 09:58

I'll be speaking at the QSI base camp on the 16th of December about my experience regarding production deployments.  This won't be technology specific so if you are in the linux world, windows world or any profession where a product goes from testing to production... this will be for you.

Where:     QSI Training Center : 440 Polaris Parkway, Suite 500  
When:      Wednesday, December 16, 2009.  Starts at 5:30 and goes until 7:00 p.m.  
RSVP:       Anji Morey @ amorey @ donotspamherorshewillhurtyouQuickSolutions.com by noon on Tuesday, December 15!

Currently rated 4.7 by 3 people

  • Currently 4.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

PDF forms and Linq?

by Jesse 27. November 2009 09:28

Just stepped into a new project and ran into a rather interesting problem that I may have a ninja-like solution.  Here's the story ...

You have a collection of PDF documents, all forms (meaning you can fill them out and print them, but not save a filled out copy) and a 4 year old way of doing it.  After digging into it a bit, I realized that I can save them a ton of time/money/effort today and tomorrow by switching them out to something that isn't pay to play AND making it maintainable.  My best idea -- creating a class that mimiced the pdf in a way and using custom attributes as the form field keys.  Should be a simple wire-up from there!  Then it hit me ... why bother with custom attributes?  What if the code could write it up, like Linq, just make sure the values line up and you're good! 

Wait what?  For one, I really don't think I'm a kungfu master in code, so how could I even BEGIN to think I could write my own ...dare I say Linq to pdf?  Is it even possible?  Well, anything is, and I think I got a bead on it.  Follow me on this and more importantly, tell me what you think...

The most important part of this is the end result, the form itself, which happens to be exactly where it starts.  It alone defines the data structure and any class that would be generated for/by it.  Self defining ...just like a database table.  So going with that as truth for both before and after, in theory, the code would have to generate a mapping from a pdf form to an object.  This would be a PERFECT use of this.  If the form changes, updates, upgrades, drag/drop and you're updated object is there and good to go.  My head's starting to hurt from this idea ... because it MIGHT be possible.

I know what I'll be working on this weekend...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

TDD Chronicle

by Jesse 6. October 2009 14:14

I just started a new feature and I've seen a lot of questions surrounding "how do I _START_ with tdd?" because, well, sometimes its not straight forward.  So this will be a hot and loose blog post full of screw ups and how it all plays out.  No really, if it don't work the first time ...theeennn it doesn't work.  Anyway, here we go.

My first thought was break out notepad, write out what it should do and how I think it should work.  Here's what I wrote ...

Scheduling Service

When given a schedule and a room
 adding a list of events to that room should occur

and I stopped.  There's more than one type of schedule -- say the user does a one off, and then does a list of 50 (something that recurs) ... so already I need to go back and change stuff as such and had to stop myself again More...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Methods

All your base are belong to notepad

by Jesse 28. September 2009 20:03

I was creating a virtual this evening in prep for moving boxes around on my network and I did something rather magical.  Long story cut REALLY short, I associated notepad with .exe file extensions ... which seems like no big deal, UNTIL you try to undo it.  Now if you let this simmer for a minute ... you have no regedit, no explorer, no command prompt, NOTHING with a .exe will run in anything except notepad.  They're done, gone, bye bye ... ok not GONE but ... just WOW.  What's worse, I'm not the only person who has done this

As for the fix, make yourself a registry key with the following data (in yep, NOTEPAD!), save it as whatever.reg and double click and merge it (worked on 2k3 and looks like it could work on a lot of other versions, vista)

[HKEY_CLASSES_ROOT\.exe]
@="exefile"
"Content Type"="application/x-msdownload"

[HKEY_CLASSES_ROOT\.exe\PersistentHandler]
@="{098f2470-bae0-11cd-b579-08002b30bfeb}"

Anyway, just thought I would share.  Oh and restart after you un-do the snafu and expect it to be ...um, angry.  Yes, I'm saying you might have to/want to just ... reinstall.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Opinion: Software Dev is more complex? No, it's software envy and the oversimplification.

by Jesse 29. August 2009 10:41

I was listening to .Net Rocks #476 and I heard multiple times that they're leaving the one man shop behind and so on and so forth and complaining how they've been left behind and its too complicated for someone to pick up.  I whole heartedly disagree on every single level.  Software isn't more complex, its more about software envy and oversimplification that's the rudimentary problem. 

A few years back I was that 3 man shop.  I, like a lot of others, would go to the microsoft conferences and watch all the gee wiz bang cool stuff and would genuinely WANT to do what I had just learned about.  Then reality set in once I'd get back at the office... More...

Currently rated 4.3 by 4 people

  • Currently 4.25/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Software | Opinion

The Power of Social Networking

by Jesse 17. August 2009 20:27

Previously I blogged about my experiences of social networking done right and ...well wrong.  A while back, the power of social networking got me an interview with 10TV regarding the 70/71 split in downtown Columbus and the 1.6 billion dollar project that should begin soon.  A few phone calls and an hour later, I was talking to Karina Nova about how I make my way home every evening and a good part of my interview made it on the 5pm news.  Nice hu? More...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

About the author

Like the description says, at my core, I'm a scientist and engineer.  I came from humble beginnings on a 486DX2 Packard Hell playing doom2 on IPX to in a small time retail shop and got into hardware (ISO layers FTW!) and it was all downhill from there.  I'm infinitely curious about almost everything and always wanting to know.

According to personality tests (real ones) I classify under "Rational" more specifically, a Fieldmarshal.  I think there's something to that.

Some of the stuff I'm currently into/researching...

Sitefinity

Ninject

Subsonic 

Currently working on ...
i did the hundred


and some extra stuff

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's, their brother, their dog, cat, ferret nor gold fish's view in anyway.  At all.  Ever.

© Copyright 2007-2009