Development
Pricing software
It seems that people make some rather interesting assumptions regarding software pricing. When talking about commercial products, there is a wide variety of strategies that you might want to push, depending on what exactly you are trying to achieve. You may be trying to have a loss leader product, gain reputation or entry to a new market, in which case your goals are skewed toward optimizing other things. What I want to talk about today is pricing software with regards to maximizing profits. Probably the first thing that you need to do consider the base price of the...
The NIH dance
I started thinking about all the type of stuff that I had to write or participated at, and I find it… interesting. Database – Rhino.DivanDB (hobby project). Data Access – Multitude of those. OR/M – NHibernate, obviously, but a few others as well. Distributed caching systems – NMemcached – several of those. Distributed queuing systems – Rhino Queues actually have ~7 different implementations. Distributed hash table – Rhino DHT is in production. Persistent hash tables – Rhino PHT,...
NIH alert! Writing my own RPC systems
Let us see if you can help me here, I found myself facing a rather unpleasant realization, in that I need to communicate between two processes (that compose a single system) with some rather draconian measures about how they are going to be used. Quite simply, I need to expose an interface with ~25 methods on it to the second process. So far, it is pretty easy to do, right? The problem is that the first process is a standard .NET executable, which may also be run on the Mono platform while the second is a Silverlight application....
Fighting the profiler memory obesity
When I started looking into persisting profiler objects to disk, I had several factors that I had to take into account: Speed in serializing / deserializing. Ability to intervene in the serialization process at a deep level. Size (also effect speed). The first two are pretty obvious, but the third requires some explanation. The issue is, quite simply, that I can apply some strategies to significantly reduce both speed & size of serialization by making sure that the serialization pipeline knows exactly what is going...
How would you learn a new platform?
Here is an interesting problem that I am facing. I have a pretty good working knowledge of computing, and while I can usually manage to get the gist of a new technology in a short amount of time, that is only useful for talking about it, not actually applying that. I am currently trying to figure out the parts where I am missing, and plug the holes. And I am running into a bit of a problem here. A case in point, I can read Java, and I can probably write C# code in Java, but I can’t write...
Reducing friction as a standard operating method
One of the things that I am really sensitive for is friction. And anytime that I run into that, I am doing an evaluation about how much it is going to cost to remove that. Thee are two sides for this evaluation. There is the pure monetary/time side, and then there is the pure opportunities lost side. The usual evaluation is “it takes 3 minutes to do so manually, and would take a week to resolve in an automatic way”, assuming a standard 40 hours week, we would need to do something for 800 times before it make...
Answering YAGNI commentary
My post about applying YAGNI in Impleo has gotten a lot of comments, and instead of answering them one at a time, I think it would be useful to just have a post answering all of them together. Ryan Riley: I suppose I'm still wondering, how did WebForms appear as a result of YAGNI? I realize that's the original ASP.NET platform, but MVC seems simpler to me, and even simpler would be starting with HTML, CSS, and JavaScript (or, heaven forbid, classic ASP) with some AJAX. Ryan, it is quite simple. It is all...
What kind of logging should you do in production?
That really depends on the type of application that you write and what kind of operations team it is going to have. I have applications that I setup, then forget about (this blog being one of them). In those types of applications, having a log in production is a burden, I need to purge it occasionally, or write the code to purge it automatically. Then I have applications that have a strong operations team, where people are looking at the application every single day. An alert raised from the system is actually going to be looked at...
YAGNI, I told them, millennium hand and shrimp!
I am running a long experiment with myself to see whatever you are gonna need YAGNI. So I went way back to this: And this: This is an application that I am explicitly growing organically, only adding things as I really need them. It is working so far.
Do you sign the default contract?
This is just something that came up recently in a mailing list, we were talking about copyright, ownership and such. The topic of who owns the code you write on your own time (and on your own machines) came up. The opinion of some people was that the employer may own the code even under those circumstances. It seems that it isn’t usually part of the law (that depend on where you are at, of course), but it is part of standard employment contract templates. When I started looking for a job, I insisted on taking the...
Hey you, developer! Learn a bit of business speak!
In a comment to one of my posts, Dave Mertens said: I often wish I had the luxury the throw away the current code and start from scratch. Why. Because my manager ask me how long it takes to fix just this bug. 80% of the bugs (luckily we don't have that many bugs) are fixed within 2 hours including writing tests. Than he asks me how long it takes to rewrite the damn code. It is interesting to note that the questions you ask select the answers you want. ...
Duct tape programmers
Sometimes I read something and I just know that responding off the cuff would be a big mistake. Joel’s latest essay, duct tape programmers, is one such case. I many ways, I feel that this and this says it all: Sometimes I feel like Joel is on a quest to eradicate good design practices. Let us start from where I do agree with him. Yes, some people have a tendency to overcomplicate things and code themselves into a corner. Yes, you should keep an eye on your deadlines and deliver. But...
Pair design sessions
It isn’t just pair programming that is really useful. I had a problem that I found horrendously complicate to resolve, and I got on the phone with the rest of the team, trying to explain to them what I wanted and how I wanted to achieve that. Luckily for me, they were too polite to tell me that I am being stop and that I should stop whining. But they were able to guide me toward an elegant solution in about fifteen minutes. Until at some point I had to say: “I really don’t understand why I thought this...
I wrote it, and it was horrible
I needed to handle some task recently, so I sat down and did just that. It took me most of a day to get things working. The problem was that it was a horrible implementation, and it was what you might call fragile: I don’t usually have the patience to tolerate horrible code, so after I was done, I just reverted everything, without bothering to stash my work somewhere where I could retrieve it later. That sort of code is best kept lost. Time lost: ~12 hours. I talked with other...
Areas of pain vs. frequency of change
A few weeks ago I had to touch a part of NH Prof that is awkward to handle. It isn’t bad, it is just isn’t as smooth to work with as the rest of NH Prof. I had the choice of spending more time there, making this easier to work with, or just dealing with the pain and making my change. Before touching anything, I looked at the commit log. The last commit that touched this piece of NH Prof was a long time ago. That gave validity to my decision to just deal with the pain of...
How to lead a convoy to safety
I recently run into a convoy situation in NH Prof. Under sustained heavy load (not a realistic scenario for NH Prof), something very annoying would happen. Messages would stream in from the profiled application faster than NH Prof could process them. The term that I use for this is Convoy. It is generally bad news. With NH Prof specifically, it meant that it would consume larger and larger amounts of memory, as messages waiting to be processed queued up faster than NH Prof could handle them. NH Prof uses the following abstraction to...
The Least Common Denominator approach
I was talking with a team about their project, and doing a very minor code review. Naturally, one of the things that I checked first is the data access portion of the application. I looked at the data access code in a sense of shock. I was on a phone call with the team, with one of them speaking and I interrupted him to say something along the lines of: “Guys, the nineties called and they want their handed rolled data access back!” Just to give you an idea, when I am saying that the code has...
Let us burn all those pesky Util & Common libraries
This is a post that is riling against things like Rhino Commons, MyCompany.Util, YourCompany.Shared. The reason for that, and the reason that I am not longer making direct use of Rhino Commons in my new projects is quite simple. Cohesion: In computer programming, cohesion is a measure of how strongly-related and focused the various responsibilities of a software module are. Cohesion is an ordinal type of measurementand is usually expressed as "high cohesion" or "low cohesion" when being discussed. Modules with high cohesion tend to be preferable because high cohesion is...
The DAL should go all the way to UI
My recent post caused quite a few comments, many of them about two major topics. The first is the mockability of my approach and the second is regarding the separation of layers. This post is about the second concern. A typical application architecture usually looks like this: This venerable structure is almost sacred for many people. It is also, incidentally, wrong. The main problem is that the data access concerns don’t end up in the business layer. There are presentation concerns that affect that as well. Let us take a look...
Application structure: Concepts & Features
I spoke about this topic quite a bit in ALT.Net Seattle. This is mostly relating to application architecture and how you structure your application. This is the logical result of applying the Open Closed and Single Responsibility Principles. Feature may not be as overloaded a term in our industry as a service, but it still important to define exactly what I mean. A feature, in my eyes, is a discrete part of the application that perform some operation. That is pretty vague, I know, but I hope that the examples I am going to go through later would make...
Ideal deployment disaster
Today we botched deployment for production. We discovered an unforeseen complication related to the production network topography which means that (to simplify) transactions wouldn’t work. I am happy about this. Not because of the failed production deployment, but because of how it happened. We worked on deploying the app for half an hour, found the problem, then spent the next few hours trying to figure out the exact cause and options to fix it. We actually came up with four ways of resolving the issue, from the really hackish to what I believe that would be appropriate, but would...
Production Errors Best Practices
I have been practicing deployment lately, and today we have gotten everything squared away very nicely, only to be confronted with a failure when we actually run the app. The error was: KeyNotFoundException, because we forgot to move some data to the QA database. We fixed the error, but I also change the error message that we were getting. Now, we get the following error for this scenario: Rhino.ServiceBus.Exceptins.InvalidDeploymentException: ERROR_ORDER_ATTRIB_NOT_FOUND: Could not find order attribute with the name: CorrelationId This is usually an indication that the database has not been...
Typemock Open AOP
I just stumbled upon Typemock Open AOP, I know about as little as it is possible to know about this, but I am going to find out more, fast.
It looks like the idea solution for a number of problems that I am facing at the moment. I wanted the power that TypeMock has for a very long time, and it certainly looks like the ideal AOP story. From talking with Eli in 2007, the TypeMock approach impose an overhead of about 5%, which is quite reasonable, in most scenarios.
Why startup times of applications MATTER
Very often I see people trading startup performance for overall performance. That is a good approach, generally. But it has huge implications when it gets out of hand. There is one type of user that pays the startup cost of the system over and over and over again. It is YOU! The developer is the one that keeps restarting the application, and overly long startup procedure will directly effect the way developers will work with the application. Not only that, but since startup times can get ridiculous quickly, developers start working around the system to be able to avoid paying...
Better to release early and be ridiculed than just ridiculed
The title for this post is taken from this post. I released NH Prof to the wild in two stages. First, I had a closed beta, with people that I personally know and trust. After resolving all the issues for the closed beta group, we went into a public beta. Something that may not be obvious from the NH Prof site is that when you download NH Prof from the site, you are actually downloading the latest build. The actual download site is here. NH Prof has a CI process that push it to the public whenever anyone makes a...
Social Engineering in Software Development: If it doesn't hurt, it doesn't matter
I am a firm believer in laziness. But as a contra weight to that, I also believe in responsibility. I made a mistake with the back office for NH Prof. Instead of setting the trail date for 30 days, I set it for one month. It wouldn't matter that much, except that this is February now, and the month is only 28 days. It was pointed out to me, and I realized that I had, inadvertently, misled my users. It is acceptable to make mistakes that counts against you, that is just tough luck. It is not acceptable to make...
Trading safety for simplicity
I many situations, I see people trying to look for technical solutions in order to prevent bugs. Typical example are "how do I prevent users of my API to do XYZ" or "how do I force developers to always do things in a certain order" or "how do I validate [complex state] at every point". The intent is good, but the problem is that the issues that is trying to be solved is usually big and complex. The solution, as well, going to be complex. Moreover, the solution is likely to be fragile. At any event, it is going to...
70% of my job is Social Engineering
It has been over a year since the last time that I actually shipped software for production. As the NH Prof beta shipping has reminded me, this is not a trivial task. Actually, we had relatively few problems with NH Prof itself, it was with the web site that I run into a few teething issues. I am afraid that I treated the site as an afterthought at first. Anyway, that made me reflect a bit over the last year. I discovered a very surprising truth. Most of what I do recently is not strictly technical. Oh, there is a...
Can you succeed without good people?
The answer is a sound yes, but for a given value of success.
A bad team can still get a product out, and that product may even be successful. But the cost that this requires is far greater than it would have been otherwise, often to the point where you have no choice but to scrap the project. The really sad part is that some people accept this cost as the true cost of building software.
Oh, and good people doesn't necessarily equate to experts.
You need a few good people, but the rest of the team can follow fairly simple check list...
Parallel Monologues
I was sitting in Claudio Perrone's talk about agile tales of creative customer collaboration. It was a good talk, and the first one that I saw that actually had a teaser video.
One statement that he said really caught my attention: Parallel Monologues.
I really like the term :-)
Implementing Methodologies
I am writing this in a bar in Malmo. Sitting with a bunch of guys and discussing software methodologies. I had an observation that I really feel that I should share.
Most software methodologies are making a lot of implicit assumptions. The most common implicit assumption is that the people working on the software are Good people. That is, people who care, know how and willing to do.
This work, quite well, in the early adopters phase, since most early adopters trend toward these set of qualities anyway. The problem is when the early adoption phase is over, and the methodologies hit...
Building Frameworks: It is one day or three months
Quite often, people remark to me that I set unreasonable time estimates for work because I am somehow much better than anyone else. I strongly disagree with this statement. Both the qualitative assessment of my skills, and that this is an unreasonable timeframe.
There are several things that I am doing that I think that people are ignoring. One of them is not starting from zero, but starting already at high speed. But that isn't the major thing here. The major thing is that people fail to notice what I am giving those estimates very well defined things. You want to...
Stealing from your client
I had a (great) talk yesterday, introducing Active Record. During this talk, I reused Jeremy's statements about data access. If you write data access code, you are stealing from your client.
Frans Bouma puts it beautifully:
No customer should accept that the team hired for writing the line-of-business application has spend time on writing a report-control or for example a grid control. So why should a customer accept to pay for time spend on other plumbing code? Just because the customer doesn't know any better? If so, isn't that erm... taking advantage of the inability of the customer to judge...
What questions should you ask at the beginning of a project?
Regardless of the actual project, I usually ask the following questions. Scalability Requirements - How many users are we expecting? Expressed as users per day. As part of that, however, we also need to consider spikes in traffic, and if we need to handle them. Distribution Requirements - How many data centers are we going to run on? How many machines?Numbers I want to hear: 1, a few, lots. Security Requirements Authorization Requirements - Role based? Data driven? Dynamic? Rule based? Sensitive data - Do we store any? If so, how secure do...
Not so Impressive
I had hard time deciding what examples I should give about what is impressive to me and what is not. I didn't want to use the real world scenarios, but I did want to give concrete examples. Fortunately, I did manage to think of a couple of good examples. Distributed Grid and Distributed Caching. Both of those are considered hard. In the sense that it takes a lot of expertise to build them. They are also one of those pure technical issues that developers love, no need to deal with pesky tax laws or understand why delinquent customers...
Build the tools that aren't there
This is strongly related to my posts about Tools Matter. During the last six months had several conversations with people about their Xyz processes. In several cases, my response was a polite version of: "This Is Broken, Badly" and "You should automate this part". I am a great believer in automating just about everything that move (and if it doesn't move, kick it until it does!). In those conversation, the response was usually, "Yeah, we thought about doing that, but Abc does things in a way I don't like and Efg isn't compatible with our Foo requirements". And that...
Requirements 101: Have an automated deployment
If you don't have an automated deployment, it generally means that you are in a bad position. By automated, I mean that you should be able to push a new version out by double clicking something. If you can't get automated deployment script in under an hour, you most certainly have a problem. Sometimes, the problem is with the process, you don't have the facilities to do an automated deployment because parts of the deployment is sitting in people's head (oh, you need to configure IIS to use Xyz with the new version), in other cases, it isn't there...
A question of Scale
One of my routine set of questions when I am coming to a new codebase is: "What is the expected load on the system?" or "How big do you need this to scale?" I have several variant of the question, including, "What precentage of your budget is dedicated for scaling scenarios?" In plenty of cases, the answer that I get is vague. There is not definite scaling requirements, but the client want to be able to scale. Here are a few rule of thumbs that will help you to know if scaling is even an issue...
Logging, Auditing and Alerts
Udi has a few things to say about logging, in response for my logging with AOP post. As usual, I agree with Udi. :-) In particular, I am in agreement with this: In broader terms, all logging goes in framework-level code. For smart clients, one really good place to put logging is in your Command infrastructure - every time a command is invoked, log it and the args. For data access, well, any decent O/R Mapper has a lot of logging already, just use it. For communication, ditto. Funny that just last week this was one...
I'll get to your application in a week - First, we need to build the framework
Jeffrey Pallermo posted about a scenario he encountered: I had a conversation with Kevin Hurwitz about developer tendencies. Kevin related a project he consulted on. He came in after over a million dollars had already been spent by the client, and he found the following: Not a single feature had been delivered (save a few half-finished screens) The team had spent all the time creating an application framework that, when finished, would make the application practically create itself. ...
Rhino.Queues.Storage.Disk
The first thing you should know, the code for this is here: https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/experiments/Rhino.Queues.Storage.Disk After my disastrous attempt to get an off the shelf embedded storage that can actually handle multiple threads with a half way decent performance, I decided that I really have to write my own. I am pointing this out to all the people who think that my first instinct is to write my own. Here is the API that it has: using (var queue = new PersistentQueue(path))
{
using (var session = queue.OpenSession())
{
session.Enqueue(new byte[] { 1, 2, 3, 4 });
session.Flush();
}
using (var session =...
How many rewrites?
I am working on a pet project for a while now, it is fun, and it is nice, but... takes a look how many times I had to rewrite it: https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/branches/rhino-queues-1.0 <-- final version branch https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/branches/rhino-queues-bdb/ <-- with Beckley DB https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/branches/rhino-queues-firebird/ <-- FireBird https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/branches/rhino-queues-sqlite/ <-- Sqlite https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/branches/rhino-queues-with-disk/ <-- custom persistence https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/experiments/rhino-queues/ <-- initial playground That was... interesting. And I do think that there is value in restarting so many ways, because now I have a much better...
Logging - the AOP way
Logging is probably the most mentioned sweet spot of AOP. Probably because it is the simplest and most straightforward example most people can think of. I remember going over a piece of code that handles billions of transactions a day(that is for you, Jdn), and seeing something like this: public void DoSomethingInteresting(string arg1, int arg2)
{
LogGateway.Enter("DoSomethingInteresting", arg1, arg2);
try
{
// actual method code
LogGateway.Success("DoSomethingInteresting", arg1, arg2);
}
catch(Exception e)
{
LogGateway.Error(e, "DoSomethingInteresting", arg1, arg2);
throw e;
}
finally
{
LogGateway.Exit("DoSomethingInteresting", arg1, arg2);
}
}
That was repeated for each and every method in the system. It was horrible.
I don't care how you do it, but there are at least 7...
There is no such thing as a single developer project
There are always at least two people in any software project: The developer who wrote the code. The developer who read the code. They are never the same person, even if just by temporal dissonance.
The Sewer Architecture
On Friday, I had an encounter with the sewers at my house. On Call team has came and fixed the issue, which was a plugged pipe somewhere down the street very fast, so no harm was done (although checking the sewers just after taking a shower is not my idea of fun). That did, however, let me learn a bit about the way sewers are constructed. Broadly, the sewer is based on the idea of pipes and pools ( at least, those are the Hebrew terms, translated ). The idea is that the sewer flows in the pipes,...
Impedance Mismatch and System Evolution
Greg Young is talking about the Impedance Mismatch, replying to Stephen Fortes post about Impedance Mismatch from a while back. Greg and I have a slightly different views regarding the details of many of the things he is talking about, but we are in agreement overall. You might say we take different approaches to the problem, but with the same overall direction. What I would like to talk about in this post is specifically this statement from Stephen: My first problem with ORMs in general is that they force you into a "objects...
[Unstable code] Why timeouts doesn't mean squat...
Because they aren't helpful for the pathological cases. Let us take this simple example: [ServiceContract]
public interface IFoo
{
[OperationContract]
string GetMessage();
}
var stopwatch = Stopwatch.StartNew();
var channel = ChannelFactory<IFoo>.CreateChannel(
new BasicHttpBinding
{
SendTimeout = TimeSpan.FromSeconds(1),
ReceiveTimeout = TimeSpan.FromSeconds(1),
OpenTimeout = TimeSpan.FromSeconds(1),
CloseTimeout = TimeSpan.FromSeconds(1)
},
new EndpointAddress("http://localhost:6547/bar"));
var message = channel.GetMessage();
stopwatch.Stop();
Console.WriteLine("Got message in {0}ms", stopwatch.ElapsedMilliseconds);
On the face of it, it looks like we are safe from the point of view of timeouts, right? We set all the timeout settings that are there. At most, we will spend a second waiting for the message,...
The small difference between OK Code and Good Code
This is OK code: def LockItem(itemKey as string):
while true:
result = PUT( "lock of "+itemKey, "requiredValue" )
break if result is SuccessfulUpdate
// we don't sleep, the remote call take care of spacing the calls in time
And this is good code:
def LockItem(itemKey as string):
while true:
result = PUT( "lock of "+itemKey, clientName )
break if result is SuccessfulUpdate
// we don't sleep, the remote call take care of spacing the calls in time
The only difference is with the value we set, and that is never used by the application.
Why is this important?
The difference between derivation and innovation
Occasionally people ask me what I think of tech X or tech Y. Usually it is something new that just came out and made a lot of noise in the blogshpere. My response is usually something along the line that: "I seen the promo, but it has the same plot as all others, so I skipped it." It tends to surprise people. Let me try to explain this with a bit more depth. The first problem that we have to deal with is that there is only so much that one can learn. As such, I have...
Use the right tool for the job
Roy is talking about certain dogmatic approaches in the ALT.Net community with regards to Type Mock. Go and read the comments, the thread is far more interesting than just the post. Now that you have done so, let me try to explain my own thinking about this. Type Mock has the reputation of supporting unmaintainable practices. You can argue if this reputation is accurate or not, but it is there. In fact, from Type Mock's own homepage: Saves time by eliminating code refactoring and rewriting just to make it testable Here is...
Zero Friction & Maintainability
You probably heard me talk about zero friction and maintainability often enough in the past. But they were always separate subjects. When I prepared for my Zero Friction talk, I finally figured out what is the relation between the two.
I talk about zero friction as a way to reduce pain points in development. And I talk about maintainability as a way to ensure that we build sustainable solutions.
Let us go back a step and try to realize why we even have the issue of maintainability. Bits do not rot, why am I so worried about proactively ensuring that we will...
Actively enforce your conventions
Glenn posted about a test I wrote PrismShouldNotReferenceUnity, in which I codified an assumption that the team made.
This is something that I try to do whenever I decide that I will have some sort of convention. If at all possible, I will try to make sure that the compiler will break if you don't follow the convention, but that is often just not possible, therefor, tests and active enforcement of the system convention fill that place.
Wait a minute, I haven't even defined what a convention is! By convention, I means things like:
All services should have a Dispose() method...
Go with High End Solutions
About a year and a half ago, I start an exciting new project (there is a demo of the actual project here). The actual application is fairly complex, and has some it gave me the chance to explore some very interesting ideas. Rhino Security is a generalization of the security scheme used in this project, and it is pretty much the driving force for Rhino Igloo. But that is not what I want to talk about.
What I do want to talk about is the infrastructure that we used for the project. We used IoC, OR/M, AoP, MVC and many other...
Frequent check ins frequent integration
A few days ago there was a thread in the ALT.Net mailing list about the frequency of check ins. Here is my opinion in this matter:
The devil is in the details
Quite often, I hear about a new approach or framework, and they are interesting concepts, with obviously trivial implementations. In fact, the way I usually learn about new approach is by writing my own spike to explore how such a thing can work. (As an alternative, I will go and read the code, if it is an OSS project). The problem is that obviously trivial implementations tends to ignore a lot of the fine details. Even for the trivial things, there are a lot of details to consider before you can call something production ready....
Zero Friction and why Defaults Matters
Several times recently I had to answer why I care so much for defaults if they are something that I can change. My answer is usually a derivative of "defaults matters". I have come to understand that this is not a sufficient answer and I need to clarify it. I have talked extensively about Zero Friction environment and why I care so much about it. It is about how much I have to fight the tools that I have in order to get what I want. I spent much of yesterday moving Rhino Tools from MsBuild to...
Handling dependencies in a one assembly
There were several comments for my recent post about the disadvantages of creating a single assembly for a project, instead of the more common multiply ones. The main one seems to be related to dependency management. How you can be sure that the UI isn't accessing the database, and other fun violations of layering. I have to say that I don't really have much issue with that. I want good layering, but I find that code style in a project tend to keep consistent over a long period of time in any reasonable time. As such, once you...
The two project solution
Back to technical content :-) This post from Kyle Baley got me thinking about my last few projects. In them, I trended toward the assembly per logical layer of the app. So I had things like: MyApp.Model MyApp.Web MyApp.Services MyApp.Infrastructure MyApp.Tests It worked, but at one point I found myself managing 18 projects solutions, and that was only because I was committed to reducing the number (otherwise it would have been much higher). I hear about people talking about 30 - 60 projects in a single solution, and there are people with more. Considering the cost of just managing...
Disinterest in technology
I just and took a look at the recent Dot Net Rocks show, as a way to look at "what the market is thinking about". I got some interesting responses from looking at the titles. I haven't listen to all of them (not by far), but I won't let that stop me from commenting. Adam Nathan on Popfly and SilverlightNot interested at all. Something that belongs to another planet as far as I am concerned. Combining Popfly (some sort of purple duck, I understand) and Silverlight puts it on the far reaches of Saturn, as far as I am...
What ready-for-production means?
During the past two weeks I built a system that is estimated at roughly 2 man months. No, I am not a coding monster, and I go lightly on the caffeinated beverages. I did that by explicitly stating that the code will have all the required features, but it will not be ready for production. It is important to understand the difference between such an effort and demo driven or spike driven code. In both later cases, the main goal is to get something that works, without regard to maintainability or long term survivability of the code / effort. This...
Setting Up Zero Friction Projects - Dependency Injection
And then there is the issue of managing the application components. We want to keep the single responsibility principal, and we want to reduce dependencies in our application. Let us assume that we are talking about a MonoRail application. In this case, we tend to have the following distinct components: Controllers Domain Services Infrastructure Services I am not counting the domain classes here because they are not components in the strict sense of the word. I am big believer in convention over configuration, and in this case Binsor allows me to easy define convention for the project. Here is...
Setting Up Zero Friction Projects - Data Access
After talking about the advantages setting up environments where the laziest approach is also the faster approach, I want to talk a bit about the details of actually doing it. Zero Friction approach is very important for the overall success of a project, because it means that the right thing is the easy thing, so that is what will get done. Something to note is that this doesn't excuse ignorance, the developers using this approach should be able to at least understand the concepts and methods that they use. I am saying that there is no excuse for making...
Don't make me THINK!
I am having a good discussion in the ALT.NET mailing list about how to get buy in from developers for advance concepts. From my point of view, this is based solely on making it easy, transparent and simple. If you can set up a system that means that the zero friction path is also the path for good design, you are golden. In other words, A while ago I was asked what I think was a good quality for an architect. My reply was that he should set things up in such a way where the developers...
Low pain tolerance
I am coming back to a project that I haven't been a part of for about six months. It was in active development during that time, and I was happy to get back to it, since it is a really good code base, and a fun project beside. The team that handle this project is top notched, but my first reaction was something in the order: "how could you let it turn so hard!" Then I toned it down a bit and started Big Refactoring. About fifteen minutes later, I was done, which didn't match at all my initial response,...
On the faults of thinking: It is extensible, the users can add this
Two posts and a discussion yesterday has finally made it clear what my stance in regards to extensibility is. Extensibility is well and good, but if I need to extend a product from the get-go, just to get the basic functionality going, then this product blew it. The discussion that I had was about SSIS and the need to create a DateParserComponent. Basically, a wrapper around DateTime.ParseExact(). I don't mind the work in creating it, but it is very telling that this is something that you would need. The posts that help cement this thinking were Phil Haack about Convection...
A different UI approach
I have been doing some work with MonoRail recently, and I noticed that I am structuring the UI in a completely different way than the way I would using WebForms. When I used WebForms, I at first tried to make significant use of the builtin controls and components, thinking that they would make my work easier. But it turned out that they added complexity instead of removing it. Then I tried to use WebForms in as pure HTML generation capacity as possible. I made very big use of repeaters and such controls, some of which I built myself. When I...
A false sense of security
After reading my post about enterprise security infrastructure, Comlin asks: Ayende, What would you say if I give you a real world scenario:1. Server running Microsoft Windows hosts a web site which includes your security features.2. Separate server hosts database. Well, common thing isn't it?We are pretty sure that the first server(it's on the Internet) would be hacked sooner or later and the hacker will acquire admin privileges. And all we have is your "entity security" inside the BL, who needs it anyway, you will take the connection string and perform all the malicious actions inside the database! I...
A vision of enterprise platform: Security Infrastructure
I have been asked how I would design a security infrastructure for my vision of an enterprise platform, and here is an initial draft of the ideas. As anything in this series, no actual code was written down to build them. What I am doing is going through the steps that I would usually go before I actually sit down and implement something. While most systems goes for the Users & Roles metaphor, I have found that this is rarely a valid approach in real enterprise scenarios. You often want to do more than just the users & roles,...
Ignorance vs. Negligence
Recently there have been a few posts about people who... misrepresent themselves when it comes to knowledge and authority. A common question that came up in the comments of those posts was to specify who the guilty party is, if not by name, then a description. First, I want to be clear about the separation I am making. I am seeing a lot of bad code, and I posted some choice tidbits here in the past. Some of it is inexcusable in a software professional, some of it is valid, because the author is not a developer. I don't have any...
Coding Standard - Names
Names should be in ASCII and are limited to [a-zA-Z0-9_]. Anything else, is a heretic attempt to cause me, personally, problems.So speaks the guy who had to convince a company that building a platform on Hebrew# is not a good idea. In addition to that, those names should be in English, consistently spelled and have a uniform coding style. I don't care what, just that it is consistent and uniform. Nevertheless, Hungarian notation should be left to those who dreams of the coup of the pwsz and its friend, cbSize. Transcripting variables names is also a sin, and it punishable...
Not invented here, useful noneteless
I mentioned before that we built most of the batch processes without ever considerring how we would actually run them. We put a tiny bit of thought into what we would need, and built declerative attributes that specified what we wanted. We also expressed that in terms that are not tied to a particular scheduling platform, but in terms that made sense to us. For instance, we have tasks that are scheduled for "Morning", and that specifies that they should not run in holidays. Since it became clear that we now really need to suppose some way of scheduling...
Embracing fluent interfaces
Jeff Atwood is talking about languages in languages, and suggest that you would avoid using fluent interfaces to hide a language semantics. I completely disagree. Let us talk about the example. The first one deals with regular expressions: //Regular expression
Pattern findGamesPattern = new Pattern(@"<div\s*class=""game""\s*id=:"(?<gameID>\d+)-game""(?<content>.*?)
<!--gameStatus\s*=\s*(?<gameState>\d+)-->
");
// Fluent interface
Pattern findGamesPattern = Pattern.With.Literal(@"<div")
.WhiteSpace.Repeat.ZeroOrMore
.Literal(@"class=""game""").WhiteSpace.Repeat.ZeroOrMore.Literal(@"id=""")
.NamedGroup("gameId", Pattern.With.Digit.Repeat.OneOrMore)
.Literal(@"-game""")
.NamedGroup("content", Pattern.With.Anything.Repeat.Lazy.ZeroOrMore)
.Literal(@"<!--gameStatus")
.WhiteSpace.Repeat.ZeroOrMore.Literal("=").WhiteSpace.Repeat.ZeroOrMore
.NamedGroup("gameState", Pattern.With.Digit.Repeat.OneOrMore)
.Literal("-->");
I can read the fluent interface, but I need to parse the regex pattern....
Lucene as a data repository
The issue of user driven entity extensibility came up in the castle users mailing list, and a very interesting discussion has started. The underlying problem is fairly well known, we want to allow the extensibility of the schema by our end users. The scenarios that I usually think of are about extending the static schema of the application. Like adding a CustomerExternalNumber field to the Customer entity, or adding MyOwnEntity custom entity. This can be solved in a number of ways, from meta tables a schema that looks like this: I am usually suspicious of such methods, and...
Failure and trashing
Last week wasn't a very good week. The rate of work that I did vs. the work that I expected to do was very low. Basically, I should have done all that work in about a day or two. Most of the issue was because I had no time in the zone this week, meeting, pairing on other people's code, etc have taken a lot of little pieces, but the main issue was that I kept going in the wrong direction. I needed to implement something similar to Outlook's rules, but for search, where you can add more criteria for...
Scaling ALT.Net Concepts
I am having a lovely discussion with Casey (and others, of course) in the comments, I suggest that you would check it out, but I wanted to reply to this comment from him: This started at ALT.Net and the Enterprise ... where you wondered why these things are believed not to scale up to (for example) 100 developers. I suggested the reason was that the great majority of those developers were 'body count', hence you had to let the overall team take the common approach (which I referred to as simple).In that case, no these 'revolutionary' things won't scale, because you...
Simple != Poor Quality, period!
Casey commented on my post about ALT.Net and the Enterprise, and we have a good discussion going on there. But something he said triggered so many red flags that I had to go breath into a paper bag for a few moments: many 'enterprise' teams have to take whatever body count they can get to satisfy the management. And in that case you have to keep things really simple (and by definition produce poor quality code). He later went on to expand what he think is simple: In case I expressed myself badly ... by simple in that...
On the ALT.Net MVC Movie
Before watching the show: It is great that we are finally seeing signs of changes Technologically, doesn't sound much different than MonoRail Politically, great news Not sure why everyone is raving about the routing support During: Things I haven't heard in Microsoft talk so far: Unit Testing Mocking Not using the designer Separation of Concerns Maintainable by default My stuff that are being mentioned: Brail Rhino Mocks Leaving holes for the community to plug. Great things that shouldn't have caused excitement: Clean URL...
Patents, Trademarks and Copyright, Urgh!
I never understood why developers are supposed not to know about such things. This is what we do for a living, we have better known what ground we tread upon. Here is the short guide from a developer point of view: Patent - I thought of it, was the first to get to the patent office, therefor, I get a monopoly on the idea, if you try to use this, even if you never heard of me and mine, you can't use it unless I agree to it (and you pay me many gobs of money, of course).The...
The basics requirements of a developer
Something really bothered me in JAOO. A couple of the presenters had a slide that showed something like this: The Relational / OO Divide DBA not familiar with OO design Developer not familiar with SQL I asked around, and apparently there is this assumption on the Java world that developers are usually only vaguely familiar with SQL. I am not sure if this is the case in practice or not, but that just sounds insane to me. I live in the .NET world, and here I expect all developers to have a fairly good grasp of SQL and how...
A code base has its own style
Here is an observation, once a code base has reached a certain size, either in time or in size, it usually takes on a style and identity of its own. This is far more than just a coding style that I am talking about. I don't care where you put the braces. I am talking about the repeated patterns that you see over and over in side that code base. An example would be Castle-inspired projects. You are far more likely to see things named SmartXYZ or IAbcAware, with the usual implications that there are there. What are the styles...
The half life of a project
The half-life of a radioactive substance is the time required for half of a sample to undergo radioactive decay. en.wikipedia.org/wiki/Halflife Scott Bellware is talking about the rate of decay of the maintainability of a project. The rate of decay of maintainability is the measure of how fast your maintainable code looses it's maintainability after your agile development guru or consultant moves on to another project. This is a subject of a particular concern of mine, since I was often accused of building software that only I could work with. I am currently teaching an MSPD course with the...
Line count & complexity
Dave Laribee is talking about measuring line counts and code quality. He mentions that in the Ruby's community is is considered a value to express yourself in fewer lines of code. Recently I had to do some statistics over my project, and I was astonished to discover that it was closing rapidly to the 150,000 lines of code. That made me wonder what another project line count was, I was pretty sure that it would be closer to half a million lines of code, but I was floored when I discovered that it barely reached the 30,000 lines of code. There...
The Right Metaphor: Software as a garden, not a building
Sometimes it is a small change in perspective that makes a lot of the difference. Chris Holmes just made one such observation that I am going to use in the future. He argues that we should think about software as a garden that requires nurturing rather than a building which requires maintenance. The big thing here is that I can already think of some parallels that I can draw (would you really want to decide up front how the garden should look, and put concrete lines all over the place?) that are more useful than the usual building metaphor.
How to sell maintainability?
Today's Drag and Drop's UIs, Wizards and Designers are all mainly focused on the creation side of the software. They help you with the initial bit, and leave you alone afterward. This is great for a demo, but really not a good proposition for the maintainability of an application. As an example, drag a table to the form, do the designer magic, and then try to add business rules about who can see what and how to the page. Is this a maintainable approach? My answer is a resounding no! But it does make for a very compelling demo. The...
Dev / Team estimation
Udi has a post with a provocative title about estimation. I agree completely. Except: Focusing on the individual developer, getting them the latest and greatest tools may be great for their morale, but it probably won’t make a bit of difference to their actual productivity. That is not something that I would agree to. Latest & greatest tools are not something that I am particularly interested in, but having effective tools means a world of difference in my productivity. I could mention ReSharper, but that is practically cheating, since I refuse to do any amount of real work without it. Effective...
Placing complexity: Localized Complexity Zone
Another semi-post morten talk that we had today had to do about complexity. A co-worker has just found my windsor.boo file, and commented on the complexity that it invovles. We had a discussion about this. I aggreed with her that this is indeed complex, but, in over eight months of the project, it was the irst time that someone other than me had to deal with it, and for the rest of the team it Just Worked. Side note: one of the things that I am going to make sure for the next project is make sure that the entire...
Developing on dotOren
I mentioned that we are on the closing of a project, and we have already started to work on side projects and preparing for the next one. In the current project, I have setup a lot of the inrasturcture myself, and then the team started to work on it. I had a discussion with a co worker today about it, she had a lot of frustration because she couldn't work on the side project the way she was used to in this project. We setup most of everything that she needed, but one thing that she said stuck with...
In Defense of WebForms: Well, maybe not...
Mats Helander is in love with WebForms, and he explains why. I think that I have already explained why I don't agree with that, but allow me to go over his points. One important thing to notice is that Mats ignore the problem of "WebForms tries to be WinForms", because, as he says, that is usually an issue raised to explain the root cause WebForms problems. I think that this is a mistake, because the rest of the problems in WebForms are non as critical as the issue of trying to be WinForms. And the main problem there is...
Prioritization, the Dilbert way
This strip had me LOL, because it is such a true description of the way most customers want to think. I am dealing with this issue by telling the customer that if they don't give me a priority scale that I can work with, I am going to implement the system using my own prioritization method, which is based on the technical fun factor of a particular feature, and that I don't consider UI to be fun, ever. That tends to get me a list of features for the next week or two :-) More seriously, though, I am posting this...
Developing on Microsoft CRM
I am currently in the process of leading a team in a project that is built around Microsoft CRM. A while ago I posted what I consider essential requirements for working effectively with business platforms. Since then, I had had a lot of time to play with MS CRM and see what the development story is. Please remember, this is an evaluation of Microsoft CRM from a developer perspective. I don't touch on any of the other aspects that it may have. I have already started to dislike it, and I have a feeling that it would only grow more...
Tools vs. Design
Just read this, Eli Lopian talks about how you can use Type Mock in order to avoid separating responsabilities: I am going to show you just how we can manage to unit test a Simple Dialog without separating concerns I have a problem with this statement. Why would I want to avoid separating concerns? The Single Responsability Principal & Separation of Concerns are critical to building maintainable systems.
Frameworks vs. Services: On choosing the right approach
Recently there was some discussion about the CAB during which I think we found the core difference between the CAB approach vs. some of the OSS tools that were brought up in the discussion (sorry, I can't recall who first brought up this observation). Frameworks has a much higher adoption cost associated with them vs. services. Services are more easily compassable and replaceable. The general option is that services == Often Good, Frameworks == Sometimes Good. Feel free to shift the scales every which way you want, obviously I am leaning toward the services over frameworks, but others has different approaches....
Repository<T>, Syntactic Sugar and DDD
I am toying around with several ideas about the use of Repository<T> in DDD context. Right now it is theoretical because my current project has little need for DDD. At the moment, I am using the static access for Repository<T> as my gateway for the repositories.