|
-
So I've been a downer and don't want to give my reader a bad
impression. ;) I do love programming and
not all shops are as bad as I've experienced.
I've been doing this for such a short time that my experience cannot be
a good statistical sample. I hope.
When I was at DeVry the most common answer to the question
"Why do you want to be a programmer?" was "I want to make games." The reality is we can't all be game
developers. However, with the trend in
MMORGS to include extensibility points through open API's we can scratch
that itch.
Star Wars Galaxies was the first game I played that had
scripting built in. You couldn't do any
flow control or logic. But you could set
up sequences of commands to say target an enemy, draw your blaster, do a
special shot, do a combo move off the last shot, stim pack yourself for a
heal. It was not only useful, but it
gave a chance to code for fun. By
writing a few scripts and sharing them with others I felt a real sense of
worth, I was participating in making the game more fun for others.
A game that I've recently been hooked on is EVE Online . CCP exposes character data through web
services, so you can write apps to help manage your character and items while
offline. They also provide data dumps,
sql scripts that include star systems, items, material costs for making stuff...
all very important data if you were going to say, write a line of business
application to manage your Eve Corporation!
There are many open source libraries created by the community, in case
you are foreign to xml, that you can use them
to call the services.
World of Warcraft takes it in a different direction. Blizzard
exposes an in game API and hosts a LUA runtime.
This allows you to create add ins and they can register for events,
process data, and modify the UI all to make your personal gaming experience
more enjoyable. Using the scripting
language LUA along with xml markup (hmm sounds familiar somehow, scripting and
markup...) you can define your UI and just go with it. Some add-ins are just for fun like printing
"She's Gonna Blow!" in big red letters on the screen when a dragon is about to
breath fire. Some more advanced add-ins
make the UI better, like allowing you to see ALL your items in one place or a
sort-able list.
Some guilds (player organizations) require their members to
have certain add-ins to do dungeons, because they are so powerful. A popular one tracks damage done to
creatures, the health of everyone you are near, and a bunch of other stats to
help bridge the limitations of the basic UI.
It knows the special moves of
certain bosses and warns you when you are gonna get pwned.
Sometimes I can't get interested in open source projects
regarding developer tools or business apps, but for some reason I get jazzed
about making an add-in playing "Fat Bottom Girls" every time a Female Troll
starts to dance near me or "Another One Bites the Dust" when someone dies.
It's such a popular past time of developers that Microsoft
has gone so far as to create a development environment for making World of
Warcraft add-ins. No Joke and the video. It is a proof of concept about how extensible
Visual Studio is... but more importantly facilitates FUN! I swear it makes me want to reopen my Warcraft account.
|
-
In April of 2006 I was desperate to break through from tech
support and testing to development.
My wife wanted to move to Arizona to be close to family and
was being laid off. I also wanted to get
out of Ohio after living there my entire life.
I applied out of state to see what was out there and after a few
phone interviews with a company I took a job in Arizona. The company made software that runs a school
district. The product kept track of
students, classes, grades, among other things.
Very interesting since my wife is a teacher.
I was placed in a
cubical with an out of date manual to a custom development environment. The manual examples didn’t work. Many days the environment wouldn’t compile. Most of the time the
application didn’t either, bad check-ins from people at 9pm. Other days the environment threw random
reflection errors. The actual
application was developed using the company’s own framework. I would rarely get a straight answer about how
to do anything. It wasn’t like I could
just look stuff up on MSDN, even though we were using .net 1.1 and C#. In my 4 months there no one explained how to
get user input or many of the common interfaces. In hind sight there was
a lot going on under the hood which has similarities to WPF dependency
properties and command patterns. Unlike WPF, there was no resource to look up for help.
I was supposed to have a mentor. But after being ignored too many times I
finally vented all my frustration at him the one time he helped. It was sometime in my second month. I was an outsider, I didn’t work 9-10 hour
days and i didn't worship "the Framework", *angels singing*. I knew I wasn’t long for that job. I just didn’t have the ballz to quit,
especially since I didn’t have a car after moving . An experienced .NET developer was
hired 2 weeks after me. He quit after a
month on the job. I should have taken
that as a sign.
Luckily they let me go.
I was dying slowly there. I wasn’t
performing. They were going to let me go
regardless, they had an existing customer drop their product and had missed a
state reporting deadline for two new clients, a feature they already sold. I was
agitated they let me go at 8am. I mean
they could have saved me the taxi ride and $ by talking to me the night before. I’m still bitter.
They were really stupid there. They had a static library, that was mandatory
to use, one of the mandated functions to use instead of a null check was TypeCheck.IsEmpty(). This method was overloaded a million times
and performed the same function as the String.IsNullOrEmpty() method in .NET 2.0. However it did it for many classes. So it would return true if you passed it a
collection and the reference was null or the collection was empty. This is handy in many circumstances, I understand
that. However it was mandatory to use in
ALL null checks. So what is wrong with
that? Seriously… guess.
So this guy I worked with had a weird bug he couldn’t figure
out. Sometimes his application would go
in an infinite loop and just retry over and over again. On his first screen he would process some
student records and put a list in the cache, a hash table. On the second he would take the list out of
the cache, if the result from the cache was null, it was assumed the user made
it to this page due to error or there was a problem at the earlier page. So he redirected back to the first
screen. He was confused why sometimes
the app would just loop, going back and forth from both pages. So he took out the check. I tried to explain the check was fine if it
checked for NULL and only null. Since
the list being empty was a valid scenario, there may just be no students that
met the particular criteria, but a null was a problem. After 20 minutes of trying to explain the
point, the difference between a reference being null after being pulled out of
a hash table and a valid collection being pulled with no records in it, the
point was dropped.
They had some weird ideas about floating point numbers, and
doubles. They used Decimals for
everything. I once got into a debate,
losing, thought of as an idiot for challenging their views. I was confused why they didn’t use them. According to them floats and doubles were
buggy and rounded, at one point I was told “The error is in the cpu”. Basically
they were trying to explain the problem of precision.
It’s not a bug in the
cpu or in .net. It’s a problem you should have learned about
in jr. high science or math. Ok, if you take an Astrophysics class it may be
re-explained. It’s why you don’t use 3.14 as pi to
calculate the distance of stars. You need more precision or
your calculations will be off, you are only accurate to (n – 1) decimal places
where n is the least precise number in the calculation. In some cases you need a lot of decimal
places and accuracy, more than a float or double can hold. When I understood wtf they were talking about
I was like “Oh, precision, yah that’s an issue with some stuff. Um… but you can use a double for calculating GPAs”.
From the msdn documentation : “The double type can represent
values ranging from approximately 5.0 × 10−324 to
1.7 × 10308 with a precision of 15-16 digits “. 15 digits
should be enough for a GPA, not enough for distance of stars though.
I’ve told that story, partially for therapy and mostly to lead
to this point.
Many companies hire Jr. Developers wanting a regular
developer for cheap and have no interest in your training. If you find yourself at one of these places, the
best thing you can do for your career is move on. Programming is a lot like chess: to get better, find someone better then you to kick your azz, repeatedly.
Our industry does not take care of its own. Our communities do, but the industry doesn’t. Most of what we do is considered magic by the
people hiring us. Just talk to a head
hunter, they have no idea. Being
inexperienced we don’t either. If we
were doctors or lawyers we would do residency or clerkships to apply our
learning and be guided by experienced people we could look up to. You would think that seniors would step up
and mentor at a company. This is a
rarity. Generally learning is on your
own and mentors are found at user groups in 20 min conversations once a month. If you’re
desperate for mentoring… so am I.
Are my expectations too high? Is it really folly to think senior developers
should be teachers?
|
-
One thing I noticed while working at restaurants was how
weird chefs can be about their knives.
You can tell who is serious about being a chef by how they treat their
knives. Many have their own sets, those
that don’t tend to lay claim to the best in the place. Never ever use a chef’s knife without
asking. Not if you ever want a good
shift again.
Curious one evening, after seeing the head chef stop in the
middle of a big order and sharpen his blade,
I asked about the odd behavior. I
was told simply “dull knives cut fingers”.
I thought that sharp knives and
clumsiness cut fingers. The way you cut
with a dull knife is different from the way you cut with a sharp knife, if you are used to cutting with one type and
pick up the opposite, you are likely to hurt yourself.
Many times a development shop will not stop to sharpen their
knives. They are too busy cutting. The consequences are not as direct as cutting
a finger. They appear in slowdowns in
the project, late nights and headaches. If your computers are slow, you may cut
corners when debugging or testing. If
you lack a tool like Code Rush or Visual Studio 2008’s snippets, you may not
use Properties and instead use public Fields to save typing. The list can go on for ages.
Our jobs (generally) are about automating tasks and
increasing productivity. Would it not
stand to reason that we should from time to time turn toward our own processes
and try to automate some of those?
A simple example: logging.
If your application has some form of logging, I ask you how
do you go about reading those logs? Do
you or an administrator have to manually poor through text files in notepad? If
you store the logs in a database, do you have to manually query the DB when
looking for events?
You probably have written a log writer that dumps the
information in your format, do you have an equivalent reader? If not, why not? If the answer is time, I would bet you or your admin have already spent more time with the manual searching than would have been used in writing a tool.
|
-
When reading xp books and general programming practice books, there is ambiguity and conflicting points on the subject of writing the “simplest” code to get something running. “Write the simplest code to get the test to pass”.
Generally the worst code I have seen or written has been with a simplistic mindset. In other avenues of life the fastest path in getting something done is also the easiest, and the easiest solution is not the usually best. It is the same with programming. Most of the time in life the right thing to do is also the hardest thing to do.
It is easiest in a CRUD application, using .net in visual studio, to drag and drop and data bind. If your objective is to view a table or view in a database, then you are fine. As long as the application is to be simple, doing a simple thing is no problem.
There are a few things that turn this simple application into a spaghetti mess. Business rules for one. Business rules come in all forms. It’s these rules your employer hopes that you will capture in requirements and in the software.
These rules also have a tendency to change. In education it may be how and what data is to be reported to the State. In financial applications it could be the algorithm to calculate certain loans. Where is your business logic? Did you follow the simple approach and hide the logic among your data binding code? If a new loan is added or a new required statistic needs to be monitored, how quickly will you be able to implement it?
I worked on a project that was approached simply, with no thought of the future. We were developing a “functioning prototype” as quickly as we could. A constant phrase I would hear when suggesting other avenues was, “we don’t have time for that”. There was no time to sit and think about the fact that the overall project was to last for a year and that the prototype was the first iteration. We were focused only on getting the proto done.
For the first two months we were very “productive” adding functionality every day. However this was an illusion, for most of the features were 85-95% to spec. It was that last 15-5% that was going to require fine tuning of the business logic. Something that was a lot harder to do now that we were committed to a poor design. The logic ended up scattered throughout the application, duplicated in many areas. Sometimes in stored procedures and at worst horribly written string concatenated dynamic queries embedded in a button click event in a form. Sometimes it could be found in the code behind of an aspx page others in the html markup itself. Objects were merely property bags passed from one form to another. It was obvious that the business rules were an afterthought.
The cliché is “Painting yourself into a corner”. There is only so much you hack at the same un thought out mess before it becomes too much to understand, too long to change and dangerous to refactor.
Many times I see this line, “Write the simplest code to …”, used to explain why something is “Over Engineered” or as a justification for writing simplistic code.
The actual statement “Write the simplest code to get the test to pass”, expects you wrote tests. In turn, this presupposes you thought though your problem and your architecture to make it testable. Having architecture is not “Over Engineering”, its Engineering. It’s unfortunate because I want to have a good architecture. I want well factored code. However with no guidance on the job, what is a junior to do? How do you learn when to use pattern x and when not, when your seniors don’t? Not to mention groan when you ask.
I’ve been told many times that I complicate issues or that I complicate problems. I have dug deep to see if that is the case. While I obsess about my code being good enough, my problem isn’t that I over anything. What I’ve been taught in school, what I’ve read in books and blogs, and what I hear from experts in person and podcasts all jive. They all point to patterns and practices which I want to master.
My problem is I’ve worked with people who don’t care and take simplistic approaches to every day coding. They say things like “Well if I had time I would have ‘done it right’” or “Maybe one day I’ll make that [bit of code] more object oriented”. And in these environments it isn’t long that I find myself doing the same. Then I have to make a choice: leave, fight an uphill battle, or live with teh suk.
Not making a decision IS making a decision, a bad one. OOP may be an unattainable Ideal, that’s fine.
Excellence (Areté) is constantly driving toward the Ideal. [Plato]
|
-
Unlike some other careers, programming doesn’t have a well defined path. You can go in many directions and some lead to dead ends. I've been given a lot of bad advice as well as some good. This is an accumulation of the good. Object Oriented Programming
Know and learn to apply the core fundamentals: Encapsulation, Inheritance, Encapsulation, Polymorphism, and Encapsulation. In school I was told that the main benefit of OOP was code reuse. In the workplace it seems that many people don’t apply OOP because cut and paste code reuse is “just fine”.
Some pushback comes from the idea that you will never need to reuse something; that the project you are working on is too unique. But is that an excuse to write in a way that prevents reuse? Prevents testing?
I’ve grown to view OOP as a way to allow code Use. The end product of every class should be something that is Usable. It may not be reused outside of the project, but it can now be used by another developer.
Without the fundamentals of OOP you will be building on a poor foundation, both for your career and the projects you work on.
Caveat: Understand that many of your peers will not be writing good OO code. But then neither will you. Know your language inside and out
Or at least try. Is it static, dynamic, a little of both? This doesn’t mean memorize your framework, but understand how your language expresses itself. How does it handle memory? How do you write an event? Until you can answer these questions, you’ll want to pick up a reference book. For C# I recommend O’Reilly’s C# in a Nutshell. Mine is well worn with coffee stains. Having a small understanding of alot advanced concepts goes along way. Learn your basic framework classes
What do you use to retrieve data from a database or an xml document? When would you want to use a data reader or a data adapter? How do you sort a List of objects? Know when you want a hash table instead of an array or list. Build a knowledge base
If you don’t know something, know how and where to find it. It’s better to have the core concepts of what you are trying to do and not know exactly how to do it. Than it is to know a million ways to not solve the problem.
Read… a lot
The quickest way to separate you from the herd is to read outside of work. Read books, read blogs, and read your framework’s documentation. Code Complete, buy it. Consider your first year on the job just one more year of college. Except now you can afford to buy your books new. If you have a long commute think about getting an mp3 player. Not all podcasts suck. Dot Net Rocks! and Hansel Minutes are top notch. The desire to learn is greater than having the capacity. Join a users group
Users groups have people that are interested in bettering themselves and their craft. You want to surround yourself with people like that and not with slugs. Meet people and talk about what little you do know. Also, don’t try to talk above your knowledge level, you won’t fool anyone. For a while you will have a lot to gain and little to give back, hopefully that will change over time. By teaching someone else you will solidify your own knowledge. Own your mistakes
We all screw up. You will too. The worst thing you can do is not tell someone you did. Stay sane
If you find yourself overwhelmed and burning out. Take a break from programming at home.
|
-
In an attempt to be crazy famous, I've devised a few tricks and tips to help a senior developer to defend his turf from the Jr. Developer. A guy like me, that is after his job. These techniques I call UnFactoring, since they are largely the antithesis of Refactoring(Fowler). Unlike Refactoring, which attempts to reduce complexity in stagnating "Factored" code, unfactoring is ... the opposite.
Stuff Method Whenever you see a method that takes an Interface as a parameter, replace that interface with each and every field from that interface. If you can add one or two extra parameters that are used for control flow you are on your way to a nicely unfactored project. I also suggest adding at least one parameter that is not used.
If your method has a return type of an interface or class, replace that with 'out' parameter. Ten to twelve parameters is a good rule of thumb. If you can get away with more, it is preferred to properly disguise the method's intent.
Collapse Hierarchy Inheritance reduces complexity, if you have few classes that derive from an abstract base. It may be wise to collapse all the objects into one big one. Making extensive use of case statements to control the differences in behavior is also a good to make visual static analysis tools unusable. Collapse Hierarchy will freeze any Jr. Developer in their tracks, forcing them to understand all potential cases of the class. This technique is useful for adding the rigidity desired to then require the Jr. Developer to modify every case statement. The Jr. Developer will have no choice but to run to you for help, thus affirming your station in the company.
Remove Cohesion Classes that have methods acting only on their data are too easily understood. It is instead preferred to have logic that modifies a class to be outside of that class. Methods such as IsValidNonHolidayDate(); should be removed from a class entirely. Instead replace every occurrence of the call with the entirety of the method logic. This will help insure that when a bug occurs involving HolidayDates, it must be fixed only by you.
Introduce Coupling Sometimes decreased coupling occurs after a Jr. Developer has read a new fancy book. Logic separated into layers can also be combated with Introduce Coupling. Subtle decoupling occurs when objects and methods rely on interfaces instead of the implementations of objects themselves. Replace abstractions such as DataSet or ILists with the appropriate UI widget, such as System.Web.UI.WebControls.DataGrid or System.Windows.Forms.ListBox. Make sure to fill the UI widget directly in your data access code. This will insure that none of your code can be used outside of the specific context in which you wrote it. You and only you will then be able to extend that functionality.
The following were contributed from a friend:
Obfuscate Intent Naming conventions sometimes work against you. If you can, don't identify member variables in any way different from local variables. That makes the JrDev either spend a LOT of his own time figuring out what is what, or come to you for help. Use variable names such as x, i, and t extensively. This will pretty much guarantee you that you will work on this module forever, without fear that some whipper-snapper will take over some of your turf. If your language is case sensitive make sure not to standardize any capitalization.
Remove Documentation Don't comment a thing, and if you're working on someone else's module, remove the comments as you go. This coupled with Obfuscate Intent is very effective. If using C# or Java, make sure not to comment in a way that can be picked up by NDoc, JDoc or any other documentation building tool.
Hide Easter Egg Mask warning messages in your compile with local compiler settings so that the Jr Dev thinks it's something he's done and wastes a lot of his development time trying to fix them. Never check in buildable code at the end of your day, especially if a Jr Dev requires it as a dependency. By the time figures it out, sometime after hours, he'll be too tired to complain. Using these techniques will insure the slow the progress of any OOP Developer that joins your team. Your managers will grow to respect your value over time. Expect to return from vacation with a raise after you save the day magically.
|
-
1) If your Jr. Developer is interested in a new .Net technology, remind him at lunch that Microsoft is ‘teh suk’ and produces only crap.
2) If your Jr. Developer says the word "Pattern", ask him what book he read and remind him that book writers are like those who teach.
3) If your Jr. Developer is concerned about a section of code he has inherited being hard to understand, lecture him on the need to write better comments.
4) If your Jr. Developer says the phrase "Cyclomatic Complexity", remind him he is not in college anymore.
5) If your Jr. Developer attempts to write a unit test, remind him to "Do it right the first time".
6) If your Jr. Developer wishes to use a vacation day to attend a conference, refer to it in house as "Brain Washing".
7) If your Jr. Developer says the word "Refactor", ask him "You think you could write it better?”
8) Require everything your Jr. Developer writes to be static. If a threading problem emerges, blame it on him.
9) When reviewing your Jr. Developers code, if you see an interface or any inheritance, make him rewrite it, this time without "Over complicating" the issue.
10) Never, under any circumstances, offer help. Just repeat: "You can do it right or get it done. Get it done". If he can’t figure out your entire codebase the first week, he's an idiot.
|
More Posts
|
|
|