Question

I have recently joined a development project and was suddenly given the job of lead developer. My primary responsibility is to break up the programming part of the project into tasks, give these tasks to the other developers, and then make sure that the pieces work together.

The problem though is I haven't a clue how to do this. I've spent my weekend with a pencil and paper trying to figure it out but I keep coming up with a list of tasks to be worked on sequentially instead of in parallel. I've thought of maybe splitting it up into features but then you end up with tasks that require editing the same files, which could require an entire task to be completely rewritten because of how early in development we are. I could have some developers wait until the program is a bit more complete and easier to create tasks for, but then I would have people sitting on their hands for who knows how many weeks.

I had a conversation with my boss about my qualifications to do this and I wasn't given a choice in the matter. I have no idea what I'm doing, so any tips and nudges in the right direction would be greatly appreciated.

Was it helpful?

Solution

A proper answer to your question fills several books. I'll come up with a bullet list of buzz words which come into my mind about this, Google and books will do the rest for you.

  1. Basics

    • Don't go alone. Try to involve your team-mates as much as possible.
    • Travel lightweight.
    • Democracy, but not too much. Sometimes, it's not about what satisfies the biggest number of people, but what hurts the least number of people.
    • Keep what (needs to be done) and how (it is done) separate.
    • Learn about Scrum ("what"), XP (Extreme Programming, "how"), Kanban ("how much"), Lean ("what not") and DevOps ("with whom").
    • Lean also is about flow: For overall efficiency, flow efficiency is usually more important than individual efficiency.
    • Learn about Software Craftsmanship, Clean Code and Pragmatic Programming.
    • Good architecture is about maximizing the number of decisions not taken.
    • Scrum / XP / Lean / Agile is about maximizing the amount of work not done: YAGNI.
    • The Primary Value of Software is that you can easily change it. That it does what it should do is important but that's only its Secondary Value.
    • Prefer an iterative and incremental approach, use time boxes for almost everything, especially meetings, make Parkinson's Law your friend because Hofstadter's Law applies.
    • Balance team structure with an understanding of Conway's Law and Tuckman's Stages of Team Development.
    • Programming is a quaternity, it is science, engineering, art and craft all at the same time, and those need to be in balance.
    • Just because Scrum / XP / XYZ is good for someone (including me) doesn't necessarily mean it's good for you / suits your environment. Don't blindly follow the hype, understand it first.
    • Inspect and Adapt! (Scrum Mantra)
    • Avoid Duplication - Once and only Once! (XP Mantra) aka DRY - Don't Repeat Yourself aka SPOT - Single Point of Truth
  2. "What world" work breakdown process

    • Collect Requirements as User Stories / Job Stories into a Product Backlog.
    • User (of User Story) similar to Actor (in UML) similar to Persona similar to Role.
    • Refine User Stories until they meet your team's Definition of Ready based on INVEST (Independent, Negotiable, Valuable, Estimable, Small, Testable). (Scrum Meeting: Backlog Refinement)
    • Sort the Product Backlog by Business Value.
    • Don't start work on a Story before it's Ready Ready (ready according to the definition of ready).
    • Use Planning Poker to estimate the effort of Stories in Story Points. Use Triangulation Comparison to ensure consistency of the estimates.
    • Yesterday's weather is the best estimate, hope the worst.
    • Split Stories if they are too big.
    • Improve delivery culture with a Definition of Done.
    • Don't accept the implementation of a User Story before it's Done Done (done according to the Definition of Done).
    • Multiple teams on the same code base should agree on and share the same Definition of Done (especially the Coding Standards).
    • Check your progress with Burndown Charts.
    • Regularly check with your Stakeholders whether what the team delivers is what's really needed. (Scrum Meeting: Sprint Review)
  3. Story Breakdown

    • List and Describe Users / Personas / Actors / Roles (Product Owner)
    • Epic -> Stories (User Story or Job Story) (Product Owner)
    • Story -> Acceptance Criteria (Product Owner)
    • Story -> Subtasks (Dev Team)
    • Acceptance Criteria -> Acceptance Tests (Spec: Product Owner, Impl: Dev Team)
    • Start with a Walking Skeleton which is a minimalistic End-to-(Half-End).
    • Create an MVP - Minimum Viable Product.
    • Expand the MVP using SMURFS - Specifically Marketable, Useful, Releasable Feature Sets.
  4. "How world" realization

    • Use OOA/D, UML and CRC Cards, but avoid the big design upfront.
    • Implement object-oriented, structured and functional at the same time as much as possible, regardless of the programming language.
    • Use Version Control (preferably distributed).
    • Start with Acceptance Tests.
    • Apply TDD, letting the Three Laws of TDD drive you through the Red-Green-Refactor-Cycle, with Single-Assert-Rule, 4 A's, GWT (Given When Then) from BDD.
    • "Unit Tests are tests which run fast." — Michael Feathers
    • Apply the SOLID and the package principles to manage Coupling and Cohesion. Example: S in SOLID is SRP = Single Responsibility Principle, significantly reduces the number of edit- resp. merge-conflicts in teams.
    • Know Law of Demeter / Tell, Don't Ask.
    • Use Continuous Integration, if applicable even Continuous Delivery (DevOps).
    • Use Collective Code Ownership based on an agreed common Coding Standard (which should be part of the Definition of Done).
    • Apply Continuous Design Improvement (fka Continuous Refactoring).
    • The Source Code is the Design. Still upfront thinking is indispensable, and nobody will object a few good clarifying UML diagrams.
    • XP doesn't mean no day is architecture day, it means every day is architecture day. It's a focus on architecture, not a defocus, and the focus is in the code.
    • Keep your Technical Debt low, avoid the four design smells Fragility, Rigidity, Immobility and Viscosity.
    • Architecture is about business logic, not about persistence and delivery mechanisms.
    • Architecture is a team sport (there is no 'I' in Architecture).
    • Design Patterns, Refactoring and the Transformation Priority Premise.
    • Project Code is the ATP-Trinity with priorities: 1. Automation Code, 2. Test Code, 3. Production Code.
    • Regularly check with your team peers whether how the team delivers can be improved. (Scrum Meeting: Sprint Retrospective)
    • Tests should be FIRST - Fast, Independent, Repeatable, Self-Validating and Timely.

Above list is certainly incomplete, and some parts might even be disputable!

If all this scares you - don't worry, because it should scare you! Succeeding software development projects in teams is not an easy task, and rarely are people properly trained and educated in this art. If this scares you, your intuition is working properly, listen to it. You want to be prepared. Talk to your boss, get some time and training.

See Also

Further reading (online)

Further reading (books)

  • Clean Code by Robert C. Martin
  • Agile Software Development: Principles, Patterns, and Practices by Robert C. Martin
  • The Pragmatic Programmer - From Journeyman to Master by Andrew Hunt and David Thomas
  • Working Effectively with Legacy Code by Michael Feathers
  • Refactoring - Improving the Design of Existing Code by Martin Fowler
  • Refactoring to Patterns by Joshua Kerievsky
  • The Ten Day MBA by Steven Silbiger (sic!)
  • Domain-Driven Design by Eric Evans
  • User Stories Applied by Mike Cohn
  • Object-Oriented Analysis and Design with Applications by Gray Booch et al
  • Design Patterns by the Gang of Four
  • Test Driven Development by Kent Beck
  • Extreme Programming by Kent Beck
  • [if Java] Effective Java by Joshua Bloch

OTHER TIPS

Get Agile

I would suggest the following:

Editing the same files

First, use Git (or a similar concurrent versioning system). As long as you are editing different parts of the same files, you wont get conflicts. If you do get conflicts, they will be clearly marked as such.

Trying to manage a multi-developer project without Git is like trying to make a pudding without a pudding bowl. It is possible, but it's going to get pretty messy pretty fast.

As has been pointed out in the comments, Git is not a panacea, but combined with automated testing it certainly helps a great deal.

List all the features

Second, break the project up into user visible features. For example "when the user signs up, they should receive an email" or "The user can add an item". Involve all stakeholders here. Get everyone in a room, and have everyone shout out their features.

These should be user visible features, you can talk about implementation strategy later.

Write all the suggestions on index cards, even the dumb ones. Quickly rationalise the list to remove duplicates, and lay out all the cards on a big table, or even the floor.

Add in any additional cards that are needed. Say your application will send SMS text alerts. You might not know how to do that, so you have a question. Write "Investigate SMS portals" on a card. Likewise for any other big unknowns. You'll have to unpack these later. These features will probably not make it into your first sprint.

Now sort your cards into groups, shuffle them about, get a feel for them. This is your project scope.

Planning poker

Have a go at planning poker. Still with everyone together, give all the developers cards that say "1 point", "2 points", etc, up to "4 points". Also a "more" card. A point is roughly equivalent to an hour.

Go through the feature list one by one. As you read out a feature, everyone has to play a card. If one person plays 1, and another person plays 4 there's a communication problem there. One person understands the feature to mean something different from the other person. Have a discussion and work out what was actually meant and note it on the card.

If you agree that a feature is a "more", that feature is too large. You have to break that feature down. Do this in the same way as before.

As you have agreement, write the numbers on the cards in a different colour pen.

Points are better than hours

Using points instead of hours takes away the macho "look how fast I can code" thing that we developers often engage in. It's a subtle difference, but I have found it works rather well.

Now compose a sprint

A sprint is a quick burst towards a goal. Decide on the sprint length, perhaps 5 or 10 days. Multiply the number of days by the number of developers by the number of points per day.

Assume 6 points per day per developer initially. This is an achievable number. If you have 5 people, that's 5 * 5 * 6 = 150 points. In conjunction with all the developers and the management, pick features from the list, up to 150 points. That's your sprint.

Never be tempted to squeeze more in than will fit. Over-promising hurts everyone in the long run, including you.

You'll need to take account of dependencies here. For example, environment setup obviously has to be included in the first sprint. This is actually relatively easy to do when everyone is present. You have 6 brains in the room, all saying "this depends on this", etc. You can then shuffle the cards around to demonstrate dependencies.

Once you have your sprint, nothing can be added to it, it's locked for the 5 days. Feature creep will stress the team, damage morale and slow everyone down. Eventually, creep will stall a project. As team leader you have to protect your team from feature creep. If a new feature request comes in, it must be added to the next sprint. IF the next sprint is already full, something else must be taken out.

Never be tempted to squeeze in extras. Over-promising gives you around 1 day's worth of happy client, followed by 4 days of team stress, and eventually, most likely, several unhappy clients when the team can't deliver on time.

Now go to it.

Hand out cards, ask who wants to do what. You have full visibility on what is getting done, and you can count the points ticking down to zero. Have a standup at the start of each day so everyone knows who is working on what, and what has been done.

5 or 6 decent motivated developers working together as a unit on clearly defined manageable goals can achieve a pretty chunky amount of stuff in a 5 day sprint.

Maintain visibility

Make sure everyone can see what the status of the project is. Bluetack all the cards to the wall. On the left are cards that are not yet worked on. On the right are done cards.

When a developer is working on a card, they take it off the wall and put it on their desk. This maintains visibility, and keeps people from stepping on each others toes too much.

There are technological alternatives to index cards, but nothing beats having a massive paper display of the project status on the wall.

If possible, have everyone in the same room for the duration of the project. Have the stakeholders around as much as possible, ideally every day.

Burndown

You can graph your points progressing towards zero on a burndown chart. If your line of best fit crosses zero before you hit your time limit, you are likely on track. If not you may need to let your client know now, before you get too close to the deadline.

If you're going to fail, fail early.

You can make a burndown using software, but I prefer just a big piece of paper on the wall. Draw and write all over it.

Automated testing

When you have multiple developers working on the same stuff at the same time, they're probably going to break each other's code from time to time. Communication and visibility helps with this, but you're probably going to want to introduce some technology to help with finding issues.

Unit testing is the process of writing tests for each individual part of your codebase (ideally each method). Your unit tests should be run often, with every save if possible. There are many tools that can help with this, for example Karma or Rspec.

End to end testing involves testing your project as a whole, treating the internals as a black box. Base these tests on your high level business requirements, for example: "The user can sign up" or "The user can see a list of items". Protractor is a nice example of an end to end web based testing framework.

There are whole books written on testing, but having at least some acceptance tests in place can help to make sure nothing gets broken as you work on your project.

Avoiding technical debt and getting to done-done

Technical debt is a concept that describes things that will have to be cleaned up later. A common source of debt is features that were marked as done, but which were never "done-done". A done-done feature is checked in to Git, has been approved by the stakeholder, and has a test.

Don't check your features off until they are done-done. Never massage the graph. Again, this hurts everyone in the long run, including you.

This is one reason why we initially only quote 6 points per developer, per day. Done-done takes extra work, but feels great and gives the team a boost.

Editing the same files isn't by itself a problem. It's only a problem if you edit the same function to do two different things.

Basically what I would do is, divide the project into 'features' that are separate. One could be something related to network protocol handling and another one to a configuration file, and yet another to DB handling. Features are big things.

Next, you want to divide those features into tasks (stories). Those should be simple things, like "when the user clicks a button, the program will load the file", "when the program starts, it will load the configuration file" etc.

Some tasks will have to be completed sequentially ("the program will parse all the fields in the configuration file" will have to come after "the program will load the configuration file"). Others won't (you can work on the DB and network at the same time).

But most likely, you'll do it wrong, and that's where experience comes into place. You'll fail just a tiny bit (or a lot), get the time estimations wrong and your project will take a bit more time than it should have. Next time you'll be better.

I would also suggest reading "Extreme Programming" by Kent Beck. Great book that helped me when I was about to be a project manager.

What it comes down to is that you have to break your application down into functional modules and then introduce contracts (interfaces and data contracts) between the different modules. Each module can then be handed out to a different developer. When you put everything back together the contracts will ensure that these modules communicate correctly with one another.

Make sure you enforce TDD on the developers, in order to guarantee that the modules all work individually.

To give you an example of what I mean:

Let's say you want one of your developers to build a SQL logger.

You define an interface and ask one of your developers (or create a story if you're using Agile) that you would like a SQL specific logger according to the following specification:

interface ILogger
{
    void Log(string message, int level);
}

What I then expect back from a developer is the following:

  1. The SQL specific implementation for logger

    class SqlLogger : ILogger
    {
        private readonly SqlLogRepository _logRepository;
    
        public SqlLogger(SqlLogRepository _logRepository)
        {
            this._logRepository = _logRepository;
        }
    
        public void Log(string message, int level)
        {
            _logRepository.CreateLog(message,level);
        }
    }
    
  2. Any dependant code, such as an implementation for SqlLogRepository

  3. Unit or mock tests depending of what was asked for. A mock test in the case above (where we have other external dependencies), or if it's e.g. a simple utility function such as String.ReverseCharacters(string input), then I would simply like to see unit tests that test a few different scenarios.

This means that:

You and your team can now continue development using this interface. e.g.

class SomeModuleThatUsesLogging
{
    private readonly ILogger logger;

    public SomeModuleThatUsesLogging(ILogger logger)
    {
        this.logger = logger;
    }

    public void DeleteFiles()
    {
        logger.Log("user deleted files",1);
    }
}

and if you need to run your code before the SqlLogger is in place, you could simple create a NullLogger:

class NullLogger : ILogger
{
    public void Log(string message, int level)
    {
    }
}

And this is how you could test it in the meantime (I suggest looking at an ICO for dependency injection)

void Run()
{
    var someModuleThatUsesLogging = new SomeModuleThatUsesLogging(new NullLogger());
    someModuleThatUsesLogging.DeleteFiles();
}

Summary

I have no idea of the size of your project but this could be quite a daunting task and if you have never done development lead before, I would suggest that you take this task very serious and spend the next few weeks reading up as much as you can on software design and archtecture. And be very transparent about your work (software quality etc) otherwise you will quickly find yourself in a deep mess that you don't know how to get out of.

I also highly suggest that you read up on design and the object oriented paradigm. You will rely heavily on OOP for this project.

The other answers have talked about the programming aspects, but I just wanted to mention the program management aspect. I'll start with a disclaimer: I am not a program manager. I have taken one course at the graduate level for program management and my work experience involves bidding hours for small projects that are usually under 500 hours and never over 1000 hours.

But I have had to help define tasking for a lab where I had to keep 2-3 people busy for 2-4 months(part time and full time). One thing that really helped me was using project management software like Microsoft Project(I'm not sure if there's a freeware version out there, but your employer probably has something like it...ask your supervisor what kind of program management software is used at your company). In particular, I use the Gantt charts quite a bit, which is the default view in Microsoft Project. By defining all the tasks and how long you think they will take, you can get a visualization to play with.

The Gantt chart helps me most because of its visualization. Seeing tasks on paper doesn't help me a whole lot, but seeing pretty pictures and a chart certainly does. Microsoft Project also allows you to set predecessors and start dates, with the main idea being "Find the minimal amount of tasks required to be completed for task X to start". At least in my small projects, the amount of 'real' predecessors is quite small. In fact, on one project I had the problem that almost everything could be done concurrently, and had to synthesize two concurrent paths that were somewhat cohesive. E.g. I tried to make sure that if developer A ever touched the GUI, they worked on tasks that were close to the GUI as well.

It sounds like you were doing a lot of this already as far as pen and paper goes, but I always find it really helpful to actually see the Gantt charts. Looking at the tasks lined up sequentially really gets me to think "Wait, does task X really have to be done before task Y?(in my experience so far, I've been surprised how often the answer is actually 'no')"

It looks like you've graduated from being a developer to being a software engineer. Realize that managing work isn't a design exercise, but the two go hand in hand. You need to manage work being done, and that depends on how your company does development. If you have the time and resources, then look at adopting an agile methodology - there's mountains of written materials on the internet. Find one that works for you, but be aware that, like everything else, it isn't free. Adoption of any techniques involves training, learning, and failing before you succeed. If you don't have the bandwidth to handle adopting a more comprehensive technique, then doing milestone planning may be the answer for you. If you have a list of sequential tasks, it may be the case that you haven't found sequences that can be parallelized. It may also be the case that you want to segment your development into more general tasks like testing, and implementation. That, by itself doesn't solve the reporting problem, but you're managing quality. Your progression may be a sequential list, but your roles are parallel. Just a suggestion. A design that maps into work done by people is called a work breakdown structure.

There are a lot of good suggestions that other people offered up, but remember you're managing work. Sometimes you can map work concepts into the design/architecture, sometimes you can't do that so easily. There's always a way to structure work so that it trackable. I suggest going back to your manager and ask him what is important to him when it comes to communicating the state of the project. That will begin to tell you how to approach what you're doing. If it is schedule, then you want to focus on reporting progress. If it is quality, then you want to report on a suite of metrics that you'll have to come up with. If its costs, then you will probably want to look at effort. All of those things also can map into or out of the tasks.

Licensed under: CC-BY-SA with attribution
scroll top