• Housekeeping to have Habitable Code

        Are you leaving a mess that chases off good talent? I was surprisingly happy with the monolithic business transaction scripts of my previous software development gig. They were quite easy to modify and understand. They were extremely vertical and organized. It took a lot of process to get one of them up and running from scratch, but once it was there they were pretty simple.  Some codebases aren’t so easy to work with and you find yourself joining a team with a mess and thinking… wow this is why they’re so willing to pay the 6 figure salary and why they weren’t interested in having meet the team or were not asking a lot of programmer questions.

        When I was in school I worked a really low paying job. I use to live in this little 2 bedroom hovel of an apartment. I had a roommate who was never there and I played Everquest, played CounterStrike, Drank Dr. Pepper and ate all of my at work by getting meal comps for volume shifts. Volume shifts are the short shifts lunch and evening. I would then go home in between shifts to rack up another round of kills and quests.

        This apartment was a catastrophe. The bathroom door rotted off the hinge from too many steamy hot showers. The dishwasher was full of dishes from 2 years before when we first loaded it and never bought laundry soap. The floor was covered in ash from smoking, a terrible habit that I quit 5 years ago*. Ashtrays were always all the way full until we absolutely had to dump them… in the trashcan that was always full until someone eventually gave up and took it to the dumpster. Pop cans littered every space of counter top. The TV worked, but no cable. The Fridge was full of soft drinks and occasionally beers that someone brought us.

        You could say that my priorities weren’t in order… yea that’s an understatement. Anyhow, the money was there for the addictions of caffeine, nicotine, and online world domination… but groceries and laundry… weren’t exactly on the top.

        If your goals as an organization are short term gains for long term pains… you will find yourself in such a mess. If you keep charging up the technical debt credit card to get that new feature out the door at the expense of the codebase becoming unmanageable or unruly then you are heading down this path to have an apartment like mine. No one will want to live there. In fact, most people won’t even want to visit. For sure no one will come in and lift a finger to make it better without serious compensation and patience. Eventually, no one will even want to keep the place… they’ll just throw a match in and watch it all burn.

    Full story

    Comments (0)

  • Are you asking your teams to go too fast? Be aware of the use of Magic!

    In my earlier days, I use to work in a popular Bar & Grill restaurant. I’ll give you a hint, it rhymes with schmabble-schmeez. That should be sufficient to protect me from libel suit right? At any rate, it was one of my favorite jobs and I met some of the best people ever. I played a couple different roles there. I was a server at first… boy was I terrible at that. I would forget to ring in an order and the table would be wondering where their food was forever. I was 19… I think everyone at 19 is utterly stupid or at least completely self absorbed or spacey, right? Then, I moved over to hosting. That was more my speed because it was straightforward. Clean a table, seat a table, run some food. For a short while, I was an expo (Short for exposition, I think). This role was on the opposite side from the line cooks and would take food off the heating window and put the appropriate fixings and final touches on it, ordering it by the seating arrangement at the table, and then when it was ready put the ticket on it for the servers/hosts to run the food out to the table. 

    In the kitchen there were a couple roles… I think I still remember them. Fry, Mid, and Flat-top. Sometimes there was a Grill cook, but usually the Mid was a very strong player who also did that. The fry runs the deep fat fryer and the toaster ovens for nachos and such. The Flat-top would do quesadillas and other stuff on a griddle, the mid would grill chicken and steaks. Now  back in the olden days we would get a print out on a printer for each position that would say what to start making. Sometimes it would print on just the mid printer and he would call out the order… “Walking in: quesadilla 86 bacon, riblets, chick roll 86 mexi sub salsa”. The cooks would fly into action putting what they needed in the appropriate places and beginning their work. When things were finished they would plate it up and the mid would organize it into the window and pass the ticket to the expo.

    Now every so often, bad things happen in the front of house or in the back of house that would require a ‘silver bullet’. A silver bullet in kanban is the ‘expedite’ lane. It means, something needs to go out of the normal flow and get to the front of the line. This would be announced in the kitchen differently “GUYS, I need a sirloin medium, FLYING” from a server, the expo would yell “I hear you Sirloin FLYING”, the mid would yell “I hear you sirloin FLYING” the cook on the grill would yell “SIRLOIN FLYING”. There was this intensity and response to affirm that we heard what was asked and that it went all the way to those doing the work. This is the sort of visibility that I expect in a good Kanban system.

    Now, one thing that would sometimes happen in these “FLYING” situations is we would get an order like that… “GUYS, I need a sirloin well done, FLYING”… the mid cook would look at his line and make an assessment… then say this funny callback “I Hear you sirloin FLYING, USE MAGIC ON IT”…

    Very peculiar to me the first time I heard this… “USE MAGIC ON IT”. What could this possibly mean. So I watched… and waited. The mid cook pulled out the 12oz sirloin and threw it in the microwave. *GASP*. After a few minutes he took it out, threw it on the grill and gave it those premium looking grill marks and within  just a few moments we had a steak in the window ready to go out to the customer. 

    Wow that WAS magic, I thought! And I also thought it was a bit incredulous. I mean… steak in a microwave? 

    Look at our software processes these days… often times were being told to do ‘magical’ things. Software developers are very clever and very ingenious. You may be asking for a steak to be well done and expecting it of a certain quality level, but when you have an expectation of time that is beyond what the current approved processes call for… be very very aware that they may be using MAGIC behind the scenes. Skipping unit tests, skipping much needed refactoring, skipping important conversations about error condition handling or performance testing.


    Full story

    Comments (0)

  • asp.net role provider NullReferenceException on Session

    Not much of a post here, but wanted to note this so that I don't forget it. If you are writing a RoleProvider (System.Web.Security?) implementation and you are putting the authorization in the web.config...

    something like
    <location path="/Some.aspx">
    <Authorization>
    <allow role="somerole"/>

    If you do the web.config... it will not have access to HttpContext.Current.Session. I suppose the thread that is checking is not part of the worker thread that the user session is in. It's pretty strange, but I ran into this because this particular app was maintaining roles within a session variable originally before we converted it to RoleProvider. Needless to say we had to go to the source for the roles and then do some caching.

    So if you need to retrieve roles in a custom manner with caching using a 5 min sliding scale... here's a snippet that could help you.

     public override string[] GetRolesForUser(string username)
            {
                string usersRolesKey = username + "|ROLES";
                Cache cache = HttpRuntime.Cache;
                string[] roles = cache.Get(usersRolesKey) as string[];
                if (roles == null)
                {
                    roles = Database.GetRolesByUsername(username).ToArray();
                    cache.Insert(usersRolesKey, roles, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5));
                }
                
                return roles;
            }

    Full story

    Comments (0)

  • Linq Specs with Fluent NHibernate

    Welcome back to my site. Here's my LinqSpecs code that I lost from a recent article. It shows a little basics on how to use the LinqSpecs framework from NuGet to do the Specification pattern in Domain Driven Development. It's quite sweet :) (if you can put up with the resulting SQL code that it emits)



     

     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using FluentNHibernate.Cfg;
    using FluentNHibernate.Cfg.Db;
    using FluentNHibernate.Mapping;
    using LinqSpecs;
    using NHibernate;
    using NHibernate.Linq;
    
    namespace LinqSpecsDemo
    {
        internal class Program
        {
            private static ISessionFactory _sessionFactory;
    
            private static void Main(string[] args)
            {
                _sessionFactory =
                    Fluently.Configure()
                        .Database(
                            MsSqlConfiguration.MsSql2008.ConnectionString(
                                "Data Source=(local);Initial Catalog=StrategicAR;Integrated Security=True"))
                        .Mappings(m => m
                                           .FluentMappings.AddFromAssemblyOf<Debtor>())
                        .BuildSessionFactory();
    
    
                using (ISession session = _sessionFactory.OpenSession())
                {
                    using (ITransaction transaction = session.BeginTransaction())
                    {
                        IEnumerable<Debtor> debtors =
                            session.Query<Debtor>().Where(DebtorSpecs.ByLastName("peckham").IsSatisfiedBy());
                        foreach (Debtor debtor in debtors)
                        {
                            Console.WriteLine(debtor.DebtorID+" "+debtor.FirstName + " " + debtor.LastName);
                        }
    
                        transaction.Rollback(); //do no harm! :)
                    }
                }
                Console.WriteLine("Press any key to exit");
                Console.ReadKey();
            }
            
        }
    
        public class DebtorMap : ClassMap<Debtor>
        {
            public DebtorMap()
            {
                Id(d => d.DebtorID);
                Map(d => d.LastName);
                Map(d => d.FirstName);
            }
        }
    
        public class Debtor
        {
            public virtual int DebtorID { get; set; }
            public virtual string FirstName { get; set; }
            public virtual string LastName { get; set; }
        }
    
        public class DebtorByLastNameSpec : Specification<Debtor>
        {
            private readonly string _lastName;
    
            public DebtorByLastNameSpec(string lastName)
            {
                _lastName = lastName;
            }
    
            public override Expression<Func<Debtor, bool>> IsSatisfiedBy()
            {
                return c => c.LastName == _lastName;
            }
        }
    
        public static class DebtorSpecs
        {
            public static Specification<Debtor> ByLastName(string lastName)
            {
                return new DebtorByLastNameSpec(lastName);
            }
        }
    }
    

    Full story

    Comments (0)

  • The Lemonade Dilemma

    Once you have a software company, your product will inevitably change. It will probably change based on many factors, but most notably it will change to the benefit of customers who have the most money and/or customers who complain the loudest and most often.

    I have this Greek place that I go to fairly often with my wife. They, for as long as I have been going there, have always served lemonade similiar to their iced tea. In a large free pour container, from which I can assume was probably "Country Time" or some other powder lemonade mixed with water and maybe sugar. it was usually room temperature and melted quite a bit of ice nicely and just had a perfect flavor to me. No it wasn't fresh squeezed lemonade, but it was the drink I almost always had when I went there. For the longest time, I have been completely satisfied with my service.

    We went there a few weeks ago, and they had replaced the lemonade with a fountain drink lemonade... Minute Maid. Now, I'm not exactly anti-Minute Maid, but Minute Maid is the kind of lemonade that kids drink. It's the sort of sugary sweet, kool-aid-esque, syrup-y thick lemonade that you can get at just about every place in the rest of the city. I was a little disappointed... admittingly, I was verbally annoyed. Well, I let it go and a few weeks later, we went back. I had completely forgot they had ditched the favored lemonade until I walked in the door.

     

    I asked the manager, "Sir, why the change in Lemonade"

    He replied, "Well, we just had people complain all of the time that we didn't have Minute Maid, and the other just wasn't as popular"

    "Fair enough" I said.

    Now, I am honestly over the lemonade switch, despite how hard it is to tell by this story. However, I was thinking about it today and discussing it with a friend. I can think back to numerous software companies making this type of choice. They seemed to stop responding the careful analysis of the cost, profit, and existing customer satisfaction based on the way their software operated and followed the forum complaints, support tickets, and general badgering into a new way of doing things.

    My first experience with this was Ultima Online. A tragic quality blunder, but that's actually not what I am going to speak of. UO was openly PVP enabled. This meant that anyone at any time could kill anyone, anywhere (Except in towns and other certain rare special safe havens). However, as time went by, people complained and complained and some probably quit playing too. Point is, MANY people stayed around. Those people were barely considered when the game was split into two different new 'worlds'... one that was 'free pvp' and one that was 'completely safe'. Admittingly, the fun in the game for me was taking on unsuspecting travelers and such as a bandit (on one of my characters) and also playing the other side as a vigilante for justice (Anti-PK, they called them, or 'Antis' for short).

     

    My second experience with this was Planetside. The game had a great beta. It was one of the most amazing games I had ever played. I was in love with driving around a tank while my close friend, Mike, ran the large cannon. We would weave in and out of trees, bases, and over and around hills using our rapid speed and maneuvering to run over almost any ground troops and powered armors while Mike blasted larger targets like tanks and vehicles with the cannon. Well, people complained... instead of using cover, vehicles, teleports, or the other thousands of options they had at their disposal, they simply complained that tanks were too over powered because they could run over people so easily. Well the giant nerf bat came down on tanks hard (a term lovingly used to refer to a 'softening' of a game feature to accomodate weaker players). They made it so that each person you ran over slowed down your tank CONSIDERABLY and powered armors brought your tank to a complete stop. It was absurd. They took it way too far and made the tank completely useless on the battlefield because people would throw themselves in front of it to stop the tank so everyone could hit it with dumbfire missiles.

     

    My third experience with this was another SOE game, Star Wars Galaxies. I played from beta in this game as well and we had nurtered and built the game up as a community of beta testers to what we saw as a new social gaming success. A game that females would get into, a game that casual players could get into. It had a plethorae of non-combat options to get everyone involved. It wasn't just another medieval AD&D rip-off. Well, then  World of Warcraft came out and just sold so many copies. The leadership of galaxies ruined the game by tweaking and tweaking and removing everything that had made the game what it was. Eventually the game utterly failed and is scheduled to be canceled and deleted. Frankly, I am glad.

     

    One thing I have seen commercial products do, which is probably admirable to an extent, is the idea of configurability. one thing that I learned from Jez Humble in "Continuous Delivery" and from seeing it in practice is that Variants (or branching) is a bad thing! It brings development to a grinding halt or such a bad slowdown that you can hardly get anything done. Another reason that this configurability (while good intentioned) is bad is because the more complex it gets to configure your product the more you have to create "professional services" departments to configure it for your customers and the further and further you silo yourself in to being the only experts in your solution. An optimal product is a solution. It is something that is easily configurable, runs out of the box, and can be used by and supported by the densest (or just mediocre-est) of IT departments. Let's face it... look around at IT departments :) they're degrading badly :)

     

    Anyhow, I think I have sufficiently smashed enough nuts in this post so I will move on now. Remember, keep your software focused, keep it clean, keep it easy to configure, and stay true to the original solution. If people complain... take it to heart, but don't change the core of your product if it means sacrificing your existing customer base and their satisfaction.

     

     

     

    Full story

    Comments (0)

  • Automated Deployment Lessons Learned

    We have this ETL/Datawarehouse project going on at work and it uses these windows scheduled tasks to go grab data out of web services and import them into our database. There's nothing very interesting about that particular process however, deployment is always frustratingly manual and annoying because you have to update these scheduled tasks and copy the console applications and then modify config files.

    My first charter was to get every console app using the same file for connection strings. That's actually pretty easy, you just use <connectionStrings configSource="yourNewFile.config">

    You can check that out over here:

    http://stevenharman.net/blog/archive/2007/06/07/tip-put-connection-strings-in-their-own-configuration-file.aspx

     

    You create one single file for the connection strings then you add it to each of the projects that use it by using 'add as link' in the add new item dialog box. 

    The second step was creating a windows installer with a custom action. That's a bit more tricky... I found the steps of how to do that

    http://msdn.microsoft.com/en-us/library/d9k65z2d(v=VS.100).aspx#Y231

     

    The last thing I did was have to learn how to use the scheduled task COM+ API... here's where I read about it:

    http://www.infoq.com/news/2008/02/TaskScheduler

     

    There are some references on MSDN about it... here's a short sample code that I created to get me started:

    public void CreateRepeatingIntervalTask(string userId, string userPwd, string appPath,

    string triggerStartDateUtcString, short triggerDaysInterval, TimeSpan repeatAfter, string taskName)

            {

                //interval doc:

                //The amount of time between each restart of the task. The format for this string is P<days>DT<hours>H<minutes>M<seconds>S

                //(for example, "PT5M" is 5 minutes, "PT1H" is 1 hour, and "PT20M" is 20 minutes).

                //The maximum time allowed is 31 days, and the minimum time allowed is 1 minute.

                if (repeatAfter.TotalMinutes < 1)

                    throw new ArgumentException("repeatAfter must be >= 1 minute");

                if (repeatAfter.TotalDays > 31)

                    throw new ArgumentException("repeatAfter must be <= 31 days");

                string repetitionMinutesString = string.Format("P{0}DT{1}H{2}M{3}S",

    repeatAfter.Days, repeatAfter.Hours, repeatAfter.Minutes, repeatAfter.Seconds);

                ITaskService scheduler = new TaskSchedulerClass();

                scheduler.Connect(null, null, null, null);

                ITaskDefinition task = scheduler.NewTask(0);

                IExecAction execAction = (IExecAction)task.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_EXEC);

                execAction.Path = appPath;

               

               

                IDailyTrigger daily = (IDailyTrigger)task.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_DAILY);

                daily.StartBoundary = triggerStartDateUtcString;

                //http://msdn.microsoft.com/en-us/library/aa381138(v=VS.85).aspx

                daily.DaysInterval = triggerDaysInterval;

                daily.Repetition.Interval = repetitionMinutesString;

               

                daily.Repetition.StopAtDurationEnd = false;

                ITaskFolder folder = scheduler.GetFolder("\\");

               

                IRegisteredTask regTask = folder.RegisterTaskDefinition(

                    taskName,

                    task,

                    (int)_TASK_CREATION.TASK_CREATE_OR_UPDATE,

                    userId,

                    userPwd,

                    _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN_OR_PASSWORD,

                    "");

            }

     

     

     

     

     

     

     

     

     

     

     

     

    Full story

    Comments (0)

  • Organizational Values as Anti-Patterns

    I like anti-patterns… so here are a few organizational values as anti patterns. See if you can tell what these people value. Where do you think they got this behavior? How is their behavior influencing the culture around you?

     

    Delegator

                “hey, can you call Mitch, his login isn’t working. That should only take you 15minutes.” This guy stands between you and your customers and delegates every request to you with no regard to your workload, capacity, or priority. Everything is Top priority to the delegator. He often tells you how long it will take you as if to imply it’s easy so you don’t tell him you don’t have time because you’re already working on his 4 other #1 priorities. Best Defense: Make delegator choose what you will drop to do his new item.

     

    Pizza-Buyer

    “Thanks for doing this war room, let’s buy you lunch so you don’t have to leave” Has a ‘go to’ motivational tool for everyone “pizza, time off, training-of-your-choice”. Thinks that you’ll eat dogshit and love it if she just rewards you now and then with mundane things like food or a leaving at 2pm. Best Defense  –  hate pizza

     

    The Appeaser

                “Wow that is the most interesting thing I’ve ever heard about SOLID principles and TDD, Bret… now so how about those TPS reports, how are those coming?” The appeaser thinks that if they just tell you how awesome all of your ideas are that you’ll just get back to doing the tasks they want you to do so they can get back to what they were doing.

     

    The Pomeranian (Shitzu, West Highland… etc)

                “Omg arf arf arf arf OMG arf arf arf!” The shitzu gets worked up when other people get worked up and it feeds straight down to you and is in your face. They often have a solution but never explain the problem to you. If you find yourself in a meeting with no idea why’re you’re there you’ve probably been a victim of the Shitzu.

     

    The Victim

                “Ted, you’ve always been able to save my butt before… can you help me?” The victim realizes that you’re a hero and you want to save people from burning buildings. They’ll use that to their benefit by making you out to be the hero… they’ll even give you credit for it and take you out for dinner. You’re team will hate you because you always shirk the team work for the hero work.

     

    The “Nice” Threatener

                “Bill, you like this manager job and having this office don’t you?” The threatener never says they’ll can you but they got stuff they want done… if you don’t do it… well there may be trouble ok. Not much you can do here… unless someone has bigger firepower than the threatener and can get your back.

     

    The “Gut” guy

                “Sure all that scrum and PMI and ‘planning’ stuff is interesting, but what does your gut tell you on this? You don’t want to be one of those academics!” Gut-Guy was probably once very educated but has become cynical since idealism gets tiresome. “This is the real world, man”. No amount of ‘best practices’ or outside proof will convince this person that they understand the context best and you should just go with your gut.

     

    The “Experience” gal

                “I’ve been doing this for 30 years [so whatever you just said I Ignored because I know better than you do] so let’s just do it the way I know works.” Experience gal is probably wrong, but 30 years of doing it wrong has never gotten her killed or fired so it must be the right way of doing it! Experience gal and Gut guy are interestingly at odds with one another… unless they’re the same person.

     

    The “Academic” Guy

                “well let’s see it says on page 94 that you just need to write the user story on a card and then we’ll write what we want to test on the back and then we’ll estimate it using these planning poker cards” Academic guy has read a lot of stuff… he’s probably smart and knows a lot of terminology but he doesn’t really understand how it fits together in ‘the real world’. He is almost certainly at odds with Experience gal and gut guy, but is insignificant and ignored because no one listens to intellectuals. Usually they have no idea why things are best practices… they just use them blindly.

     

    The Schmoozer

                “yea we’ll be doing your review soon, just give it some time. We need to talk to the president and push some numbers around.” The schmoozer is you’re best friend… I mean he hasn’t given you a raise in 2 years because “the economy is in the crapper” or “we haven’t had reviews yet” or “no one is getting raises”. There  is never an objective goal to get anything from Schmoozer.  He just has his schtick that he probably copies straight from his bosses mouth and he’s such a pushover he falls for it… but you’re not buying it… are you?

     

    The Carrot-Dangler

                “ok so here are your objectives for this year, you make a 5 star rating on all of these and you put you in for that promotion.” Carrot dangler hangs the awesome carrot in front of you and gives you all this great ‘objective’ stuff to do for him.. (mostly just cut and pasted from his bosses objectives for him). If you like hamster wheels or treadmills this can be kindof cool… usually the objectives are easy to pretend that you’ve done them. Honestly I’m good at working for a carrot-dangler I just realize it’s an endless wheel of making them more famous and popular while you’re tucked away in your cube hammering all these things out for them they’re out making good friends up the chain and getting promoted. If you want to work for the same guy forever that’s cool just make sure he’s actually going to becoming 1 pay grade higher than you wish to become.

     

     

    So… why am I talking anti patterns?

     

    Companies say they have “Values”… “Core values” or “Cultural values” or “Organizational values”

     

    We’ve all seen them… they’re in the handbook.. posted on walls… said in a cliché-like super-cool do-as-i-say-not-as-i-do tone by smooth looking chiseled featured CXO style muckity mucks.

     

    What are they really though?

     

    How can you tell what the real organizational values are at the company that you’re about to work at are?

    Full story

    Comments (5)

  • Some ways i handle email

    You can disagree with this stuff but this is how I (try to) roll:

    • Don’t put multiple people in the TO field.
      • If you absolutely must put multiple people in the TO field (so everyone knows what you told each person), then address each person specifically in bold and repeat any relevant details to them in what you say ‘to them’ in the email.
      • Don’t use BCC that’s like talking behind someone’s back.
        • If it accidentally gets a reply all you’ll look stupid.
        • If their boss needs to know then openly cc their boss.
        • Use bcc only if everyone in the email is BCC such as to keep everyone's email addresses private when others don't know the address.
          • such as some sort of external mailing like a joke to your internal and external friends (keeping everyones address private)
          • To share training opportunities so it's not like you're saying "Hey this person doesn't know this shit, laugh at them"
    • Don’t put multiple objectives in a single email.
      • People will read until they see a ‘relevant detail’ then stop reading.
      • If you have to do it, use bullet points so they realize there are multiple things to consider.
      • Don’t use bold or say ‘note’ people ignore that because they think it’s just more stuff relevant to what you just said. Usually people emphasis ‘additional details’ so if they already ‘get the gist’ they won’t read it.
      • Don’t have email signatures. Sorry they’re just annoying.
    • Don’t use a past email as a whip when people didn’t do what you expected them to. “WHAT? It was in the email I sent you last week! You remember: The one that had 15 things in it that weren’t bullet pointed and 12 of them were irrelevant to you.”
      • This goes for wiki pages and other documentation as well.
      • If you didn’t get an answer in the affirmative assume I didn’t follow the email. Emails are assumed lost unless confirmed.
    • Emails are assumed lost unless confirmed.
      • Yes it is worth saying twice J
      • A read receipt doesn’t mean someone read it.
      • A lack of read receipt doesn’t mean they didn’t read it
        • It might mean that person boycotts read receipts (like I do because it’s an intrusion and a false expectation that you actually communicated your email properly to me and that I understood any of it)
      • Firing off a round of emails doesn’t mean you’re off the hook from then on.
    • Following up on an email is YOUR responsibility. Not the recipient.
      • Set a reminder for X days out on your email to follow up and see if they got it and understood it.
      • Ask for feedback on the email if they didn’t understand
        • You might suck at communicating with this person so you need to get feedback and tailor your style.
    • Don’t save up a bunch of stuff to email at the end of the day in one big email.
      • No one wants 1 big email at 4pm they’ll ignore it.
      • If there is 1 single thing on that list that they can’t answer or do, they will not get back to you FOR ANY OF IT.
      • If people are annoyed with lots of tiny emails, it’s not because your emails are too frequent it’s because whatever you’re sending them is useless to them. Figure out which ones are useless.
    • Don’t reply all to your own email shortly after your first one
    • Don’t recall emails. Just reply all and correct yourself. Unless it was an unintentional very large reply all or large distro then just leave it alone and suffer your fate J
    • If there is a meeting where you will see the person… just wait. Save them the email.
    • If someone doesn’t understand your email and replies with a question. Call them or see them in person. Don’t reply to the question. If they already don’t understand you then they probably will get confused with your clarification. Just call them, straighten it out, figure out how to communicate better with them.
    • Use a good subject
    • makes sense in searches
    • short
    • is not ambiguous
    • does not ask a question (let the body do the talking or people will skip the content)

     

    Full story

    Comments (0)

  • How I Focus on Software Quality



    Quality software is Code that delivers the intended andconsequential business value while also keeping a minimal amount of maintenancecost after it’s delivered.

    Here is my recipe for successfully delivering this. Take it or leave it... seriously it's just how I personally do things and i'm definitely willing to hear some feedback just don't expect me to argue that there is one best way. This is just 'my' way... one of many possible ways.

    Acceptance Test Driven Development or Behavior DrivenDevelopment is the first step.

    Let’s take what everyone is familiar working on… a defect.Generally a customer experiences some sort of behavior and it is undesirable.They call in, they are pissed, they want you to make it work correctly forthem.

    Reproduce the issue. This is first and foremost… you can’tfix something you can’t see. Reproduce the issue and while you’re reproducingthe issue gather as much information as you can about what the root cause mightbe.

    Figuring out the root cause is something that I often have ahard time explaining to people. I generally think of finding root cause as similarto troubleshooting. First if you have a problem… divide the problem in half andsee where it follows. In the case of software… if you have multiple classes orcomponents in play try to isolate them with known working components or in aunit test harness/fixture.

    Reproducing the issue in a unit test with a debugger is asure-fire way to see what is going on that is wrong.

    Note: if you cannot figure out how to reproduce the issueand it’s only reproducing in a customer’s system then your first step should beto Create More Robust Logging around the problematic area. Debug loggingin  a production environment is essentialno matter how well you use TDD or ATDD and no matter how great your programmingability is. Just be careful not to break any privacy or data storage laws(things like credit card CCV2 for example are illegal to store)

    Once you can isolate the issue to a certain area of codethen you absolutely MUST identify what components need to change to fix theissue. (DO NOT FIX YET).

    This is like a level of effort examination. Inform yourtester what all you plan on changing. You know the person who has to determinewhat will need regression tested after you go fumbling around in the code.

    Programmer:Ahh yes package A, package G, class C, Class F,method G, method Z…

    Tester: oh really you have to change package G? I guess I willhave to regression test Foobar then.

    Create all the appropriate project level reporting stuff atthis point (tasks with estimates for example, in scrum)

    Now write unit tests for every class/method that you will beimpacting with this change. Use “Right BICEP” to test and refactor as needed toadd tests (See Working with Legacy Code)

    The whole time I’m doing new unit tests and refactoring, I amconstantly going back and checking things out in the UI to make sure that Ididn’t break anything. Follow as many paths through the code as you can (preferably100% of them). Some gui based automation could help here too.

    OK NOW fix the code using TDD.

    Re-run all the automated unit tests (including your new testthat checks the bug)

    Get a code review

    Refactor as needed

    Re-run automated unit tests

    Do user acceptance testing.

    Release to customer.

    Full story

    Comments (0)

  • Scaling Scrum with User Stories

        One of the more difficult things to understand for companies who are converting from non-agile methods to agile is figuring out how to convert their requirements and support pipelines into something that works for agile teams. If you're familiar with Mike Cohn's book "User Stories Applied" then some of this terminology will be familiar to you. If you're familiar with Scrum and user stories then hopefully this will communicate a more clear 'example' or 'starting point' for you to begin scaling agile practices across larger sets of development teams.

        The classic breakdown of work in a normal organization begins at the strategic office or PMO. They will often begin strategic planning very far in advance of the development teams creating a portfolio of programs that will turn into projects of specific tactical purpose.

        There are generally two camps from here out… those who would say that the PMO and program management acts the same as it did before and Scrum and/or Agile methods fit below that somewhere. The other camp, however, is where I sit. This is the camp that says "There are no secret backlogs, there are no dual backlogs, there is only 1 single enterprise backlog that everyone works from."

        The reason I am in this came is because an organization that focuses on it's highest priority goals succeeds rapidly in the marketplace by delivering it's highest value items first and rapidly responding to the feedback that they provide.

    That's my elevator speech for it anyhow.

    So what does that look like in practice?

        Well, at the top of this food chain you have products and themes. I generally just call this layer "Themes" but please keep in mind that Themes can span multiple products and a product can span multiple themes. That is to say if Microsoft office was a product and each "word, outlook, excel, and access" are themes and at the same time truetype fonts could be a theme across office, windows 7, and ms project. This complex relationship is important to keep open and flexible because it may require coordinating multiple products to deliver a particular theme (of functionality) and it may be required to coordinate multiple themes to create a single product.

        Under themes you have Epics. Epics are the classic "Minimum Valuable Feature" that a business or stakeholder can recognize. You'll usually recognize an epic when developers say "We can't deliver all of that in one sprint, it's too big, and the business person says "well it's just not deliverable unless I get all of it". A good example of an epic would probably be an initial set of Charting in Excel. You couldn't ship charting with just 1 type of bar chart for example. Careful here because epics can undeniably turn into themes very quickly if not constrained to a certain subset of minimal functionality to be releasable. As an example, if you just said "Charting" then that would be a theme. (In my opinion… but you be the judget because it's all about your context)

        Under Epics we have user stories. These are 'features' that are recognizable to some sort of actor in the system. (Or user if you prefer). I like to say actor because maybe you're building a web service to be consumed by mashups across the globe and your company will never be developing the client application that any end users will utilize. A user story is generally a finite piece of functionality that can be indepdent of other stories, negotiable in content (finite in scope), valuable, estimable, small (enough to fit many of them in an iteration if possible), and testable (or verifiable by the customer so that they know what they got). (INVEST is a simple way to remember this)

        Once you're at the team level you break this down to tasks (mostly technical tasks). Tasks are pretty straightforward… "make getter stored proc", "Make setter stored proc", "create DDL Script", "install sql server", "configure windows server and IIS7", "create build script", "Write end user documentation on widget x"

     

    So the tricky part here is… how do customers and stakeholders interface with the team to make sure they get what they want?

     

    Short answer… you need to decide that.

        Long answer. Identify your product owner(s): Maybe you have a particularly great customer who is willing to provide you a product owner to work directly with the team and create these artifacts. Perhaps you have that but they are unwilling to create user storiesl…. Those are just too indepth for them to worry about. So you might get a business analyst/user proxy who can create the user story level breakdown. That isn’t much different than writing requirements in many ways (just more real time with development). Perhaps your customers are internal to you and there are many of them. Find someone they trust who can represent them and have them act as your product owner. Perhaps there is a ‘director of product management’ who can be your top “Theme level” product owner. Then product managers would write epics and Business analysts would write user stories.

        The tricky part here to get right is support. How do you handle listening to support and involving their feedback. My recommendation is to make that the area product owner’s primary job. Afterall, keeping your current customers happy is the most important part of a good software practice. They generate revenue, they keep buying new upgrades, they promote your software to other users, they help other users support the product, and they create new ideas and innovation for you.

        This gives them direct contact with the person closest to the team so that if a high priority customer issue comes up you can properly abort the sprint and re-prioritize if needed. I've heard of some organizations just saving 1 team member's capacity solely for support issues every sprint rotate who that is. They can be support-bitch (or support-monkey to be more PC) and rotate it around each iteration. Maybe have a stuffed dog or monkey that signifies who is on support and put it on their desk when it's their turn. That person would work with the APO and Support to create a user story around the issue, create acceptance criteria, get sizing from the team once a solution is ready, then get it into a sprint as a user story once that prep work has been completed.

     

        Support bitch would probably not have time to also develop, test, and push out a hotfix though (but maybe if they're a rockstar, right?)

     

        If you have other ideas of how to scale agile out and up including examples from your organization please drop me a line or comment here. I appreciate your time and feedback.

     

    Full story

    Comments (0)

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. Next page