Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Saturday, January 19, 2013

Continuous Team Switching?

Douglas Squirrel led a session at CITCON Budapest 2012 about Continuous Rewriting, summarizing many ideas I've heard before from Dan North or Fred George presentations into a really coherent evolutionary progression, and took the concept even further.

Like other Continuous practices, this would be as much a technical as an organizational-cultural change. It got me thinking about how this would change the team dynamics - not just inside a team, but in the context of the bigger organization.

The various Continuous practices always came about the realization that when something is rarely done, people will be bad at it and thus it will be hard, ineffective and error prone. Thus if we simply do it more often, we would get better at it.

Joining a new team and becoming an effective contributor is a process that is in need of improvement (on most teams). Getting to grips with the inherent domain complexity and the piled on technical complexity, learning the tricks and workarounds, etc. can hold back someone from being efficient for quite a while. On the other hand, having a fresh set of eyes can provide a new perspective and expose much of the technical debt the team has.

All the continuous rewrite examples so far have reduced the code size, making it understandable (though often this reduction came thanks to better understanding of the domain).

Assuming the reduced code size enables speedier onboarding of new team members, while still benefiting from the new perspective it brings, what would more frequently rotating in and out rotation team members (while never completely replacing any one team) result in?
  • Could this make spreading of ideas and practices within a company more effective and faster than the current silo'd, departmental setups?
  • Would it speed up the on the job, just in time learning of every
    developer in the company?
  • Would it improve the skill level of every developer, or would it drag everyone down?
  • Would it strengthen the company culture, simply since each person would know more other employees (given that many of us only socialize within our own team)?
  • Would it spark more cross-departmental improvements - unlike accountants or marketers, developers can jump between various areas and domains of the company with relative ease, and thus could see potential improvements. Would this make crazy IT processes (where the data passes through, without enhancement, several different teams and applications, modified effectively by only one at the middle, then be loaded back into the original source) extinct, making IT governance easier?
I don't know. But it certainly was a fun thought experiment! Feel free to add questions to the above list in the comments!

Sunday, October 31, 2010

Dealing with crunch mode

Before going any further: I think that crunch mode is not sustainable and is best avoided. I won't analyze the phenomen or its causes, there has been much written about it. However, given it definitely exists, though usually for shorter periods of time. Having had this experience a number of times, I felt I should organize my thoughts for future reference (for myself, and maybe for others too).

Some of the points below might sound like good practice for software development in general - often we only start working on process problems after they've blown up into our face. Holding retrospectives after such periods can bring quite a change, so don't miss out on the opportunity! However, we haven't even started yet, so let's step back in time.

Knowing why the close deadline is important from the beginning is crucial to keep the team motivated during this period. Working overtime for no apparent reason makes the already bad situation worse.

Have well defined boundaries for both time and scope. This is generally a good practice, but this is a must - setting out on a death march without a clear purpose is unlikely to succeed. Break things down into small (4-8 hours) tasks, prioritize them (and I mean an ordered list, not making all of them into critical priority). If the added up estimates already run out of the possible available time, cut scope. Most likely the only way it can be cut is vertical - e.g.: we will have logging, but we will work against only a single library, and won't make it pluggable for this deadline. Or we won't make the logging destination configurable (though it's a contrived example, it helps making the point).

Taking on technical debt can help. Be sure you all understand that this does not equal to crap code, unconditional copy-paste, etc.. Only introduce debt knowingly (you might want to keep an actual list of the shortcuts you have taken so you know what to fix in the upcoming releases).

Stop experimenting and move back to the comfort zone. Almost all projects involve some new element that the team is not familiar with it. If the team is just learning unit testing, they likely write the tests after they got the code to work, and are taking a long time to write them. In that situation, not writing tests for the time being could be the right choice. However, be careful to get the right message across - you are not dropping the practice because it slowsdevelopment down, but only rescheduling the learning period to some other time. Also, just like with performance optimizations, make these decisions after measuring - don't do itbased on speculation.

On the non-technical front, you can cut back on meetings, both in numbers and in duration. You might also want to schedule them so they don't interrupt the workflow. Have a status in the morning and at the end of the day, with a team lunch if more discussion is needed.

Work from home. Of course, some infrastructure is needed, and it might not be an option for everyone, especially for the person where next door is a construction site. However, saving on the commute time might could give you some extra time during the day without cutting too much into your personal life. Significant Others are more understanding if you are a bit more tired when they get to see you at least.


[Scope section was updated based on @ljszalai's comment on twitter]

Sunday, September 26, 2010

Don't repeat yourself, even across platforms

It's well known that duplication (not even mentioning triplication, quadruplication , etc.) is bad for maintainability (hence the DRY principle). I have not seen much talk around DRY with regards to multiple platforms/programming languages, so this post is my attempt to distill my thoughts and to learn about the pros/cons of applying this principle across languages/platforms.

Why would you use multiple platforms, or do a polyglot project?

Without the goal of enumerating all possible reasons, some case are:
  • Web applications need the same input sanity validation performed both client side for usability (JavaScript) and server side (whatever technology you use) for security. The same argument can be made for any N-tier application for DTOs.
  • For a portfolio of applications in the same domain, there is a need for consistency - e.g.: reference data catalog for input fields (you want to use the same terminology across the applications)
  • There can be similar logic applicable to different platforms - e.g.: some static code analysis is the same across platforms, whether or not we talk about Java or C# code, and it'd be nice to have just a single implementation.

Some approaches

Meta data driven libraries- the canonical data source is stored in some kind of a database, which contains a cross-platform implementation of the logic (e.g.: validation logic saved as regular expressions) and you have a minimal implementation in each language that is generic and data driven. There is minimal amount of code that your need to depend on in your application, which makes it a stable dependency (note I'm not talking about the code stored in the database, just the API you program against). However, the actual validation logic becomes black box from the testing perspective, and any of these metadata severely limits what you can do with it, and extension points are much harder to find - e.g.: should you want to restrict your application to only accept a certain range of zip code, how do you build that into a regexp based data driven validation framework? It certainly is possible, but hard, and in many cases expanding the framework increases complexity with significantly, and the data dictionary becomes somewhat hard to maintain.

Plain Old X Objects* appeal more to me. They are easily debuggable, can be used in isolation and offline development. They can be much richer (you can have all the errors encountered reported back to the user rather than a pass/fail), more readable (though certainly you can write readable regular expressions), and should you want to enhance/override the default behavior in special cases, you can easily override them. The problem of course is to make the same logic available on multiple platforms, in a unified fashion.

If the technology stack allows it, pick a language that runs on all parts of the stack (e.g.: Ruby/Python/JavaScript are all available as standalone and for the CLR/JVM.) The integration tests are fairly easy, just run the same tests with the different platforms.

If there is no suitable bridge for the stack, code generation is one option, which is almost the same concept as the metadata driven simple framework above, just taking out the datastore and generating classes for each of the rules to enable offline usage, debugging, etc. This has the additional cost of creating and evolving the code generator tool in addition.

Testing

Irregardless of the path chosen, the shared logic must be tested and documented on all platforms, which might be hard to do. Acceptance testing tools (fitnesse, concordion, etc.) can help, or for the data driven tests (e.g.: for validation, input string, should be valid, expected error message) a simple testrunner can be created for each of the platforms.

(Potential) Problems

  • Diversity vs. monoculture. The library becomes a single point of failure, and any bug has far reaching consequences. On the other hand, the reverse is true: any problem has to be fixed only once, and the benefits can be reaped by all that use the library. However, there might be fewer people looking at the shared domain for corner cases...
  • Shared dependency overhead - shared libraries can slow down development both for the clients of the library and the library itself. Processes for integration must be in place, etc. Gojko Adzic has a great post on shared library usage.
  • False sense of security - users of the library might assume that's all they need to do and not think through every problem so carefully. E.g.: DTO validation library might be confused with entity/business rules validation
  • Ayende has recently written a post about Maintainability, Code Size & Code Complexity that is (slightly) relevant to this discussion ("The problem with the smaller and more complex code base is that the complexity tends to explode very quickly."). In my reading the points are more applicable for the data-driven (or from there code generated) approach, where that smart framework becomes overly complex and fragile. Note he talks about a single application, and it's known that when dealing with a portfolio (NHProf, EFProf, etc.), he chose to use a single base infrastructure.

Have you done something similar in practice? What are your thoughts and experiences? Or have you been thinking about this very same topic? What have I missed? What have I misunderstood? Let me know!


Saturday, August 7, 2010

On hiring programmers - writing code before the interview

What prompted this post was this job ad for an experienced web developer by Netpositive and the discussions that it prompted - and the realization that there is no way I can explain my view within twitter's limitations.

I liked the ad because as a prerequisite for being invited to an interview, applicants are required to write a little web application (regularly read from an RSS feed, store it locally, display the posts on a page (with paging), and add Facebook's "like" functionality to the page).

Being able to conduct an interview based on code the candidate written at her own time before the interview has the following benefits:
  • the interview-fever problem is eliminated - some smart people can't solve simple problems during the interview they would be able to do in a minute under normal conditions
  • those that can talk the talk but can't apply the theoretical knowledge to real problems don't get past this filter
  • those that cannot sell themselves during the interview but are good programmers can be considered
  • as an interviewer, I can focus on what the candidate knows, can ask them to suggest ways to implement new features in an application they already familiar with
  • it is more fair for people who might not know the jargon and terminology (though they certainly should learn it later), but are good at programming
  • you can learn a lot that might not be uncovered in a regular interview, e.g.: how likely the candidate is to reinvent the wheel rather than looking for existing solutions
  • the interviewer can screen applicants for requirement analysis if needed - just give an ambiguous enough spec
  • those candidates, who just want to get a job rather than a job at the given company are likely not going to apply because of the extra effort required here. Some great candidates will not apply either; however, I think that is an OK risk to take.
The hardest thing with this approach is picking the problem to be solved -
  • should be big enough, not just a one off script, but something where some design is required, so the interviewers can learn about the candidate
  • should be small enough so a good candidate can complete it in only a few hours;
  • should be a problem relevant to the job the opening is for, not another hello world program;
  • should be such that it's not a problem if it's googleable - we all google all the time, the important part that the candidate should demonstrate an understanding of the googled solution
  • should obviously not be real work for the company - I would not want to apply to a company that wants to use my work for free to deliver to their customers.
I'm not even going to attempt to give a silver bullet solution that satisfies all the above, because - as everything in the software field - it depends on your context. However, the below ideas could be used as starting points:
  • problems from online programming competition archives, e.g.: UVa Online Judge, Sphere Online Judge, etc.
  • dedicated online screening applications, like Codility
  • using tasks (bugfix, new features, etc.) from OSS projects. Yes, it is free work in a sense, but it contributes to the applicant's resume and makes the world a better place! :)