Pokazywanie postów oznaczonych etykietą subjective. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą subjective. Pokaż wszystkie posty

sobota, 31 października 2009

Non-violent resistance

Some time ago I said that Pragmatic Programmer, The: From Journeyman to Master is quite a kitschy title.
How would you call this dedication?
This book is dedicated to all who teach peace and resist violence
JavaScript: The Definitive Guide by David Flanagan

piątek, 21 sierpnia 2009

PHP MVC vs. C# ASP.NET or the cure is worse than the evil

I started programming using C++.
Then I was writing stuff in C, C++, Pascal, Java, C#.
When I wanted to get my first job I figured out that most students work as PHP programmers, so I borrowed a book about PHP, wrote a sample application and a month later I was a PHP programmer.
I must say that in the beginning I hated every single bit of PHP. I've never written an app that I din't have to compile in order to run it. These crazy PHP constructs such as $$. Wow, they're really crazy.
What is more, I have never written a web application before. I always wrote some console / desktop stuff.
However, after about 3 months of coding on a daily basis I was pretty comfortable with almost everything I was doing. Maybe not with PHP itself, to be honest - I have never become comfortable with this language, but whole MVC pattern and its connection with web interface is so intuitive and natural that it really became my world. I still think that navigation on web pages is far better than navigation in desktop applications. When everything is identified by URL and I can open every link in another tab, I feel comfortable with interface. When I have lots of buttons and no tabs to open, I feel crippled with interface.
When I see a link like /article/show/123 or /article/edit/123 and I have Article controller and methods like show or edit, I can just sit and write code I need. I just love that HTTP protocol is stateless. I love the fact that anyone who clicks the link, be it a real user or google crawler, sees (almost) the same content.
PHP also has great template frameworks, such as Smarty. It's very intuitive and readable. The most important this is that THAT guys ;) don't have problems working with it and can easily can change the markup without affecting application logic.
Even though PHP frameworks like Cake and basically all MVC frameworks are very intuitive (in fact we were using our own MVC framework), language that drives them is really crappy. I've seen lots of PHP code, even very good PHP, and I've never seen good object-oriented patterns. Yes, there were lots of classes, but concepts such as inheritance, static objects, interfaces or abstract classes are not a part of this world. Classes in php are quite important but they are not strongly related to each other. When I think of real OO classes, I think about inheritance, interfaces that they implement, I see that some of them are more specialized, while others represent some general ideas. PHP OO in my opinion is poor man's OO. The real power in php are its associative arrays.
If I ranted about PHP flaws in its implementation of OO and wouldn't say that I was a strong advocate of not using most of its features in PHP5, I would be very unfair with people developing this language. I was always a strong opponent of using private / public keywords. The main reason was that every time someone messed up with it, we got white page of death on production server. I consider private / public modifiers to be important while compiling the code, but they become completely unimportant during runtime. Even if you declare field to be private, you can still access it using reflection of some kind. In php, when you don't declare types of method arguments, concepts such as interfaces also don't mean anything. PHP function takes basically anything and then tries to execute some methods on it. You don't have to declare interface to be able to execute some particular method on a given object. Well, you just try to execute it.
I worked with php programmers who actually used to think about types of objects they passed to functions. All interface / abstract stuff WAS implemented in the logic but not in terms of keywords. It was convention over configuration, and it worked pretty well.
Unfortunately, when someone didn't want to keep the convention, we just couldn't force them to keep it. And hell yeah, I wanted all people using my code to pass only some particular interfaces as arguments. I was unable to do that.
To sum up, I think that PHP is crappy, but it has great MVC frameworks, nice templating systems and if you want, you can write really good code in it.

On the other hand, there are C# and ASP.NET. I must say that I just love C# 3.0. It has so many useful features, great attributes, lambda expressions, generics. Some things could be better in C# 4.0, but even now it is my language of choice. C# lets you write clean and descriptive code that you would not be able to write in PHP.
However, here comes ASP.NET. I'm not talking about ASP.NET MVC - I have no experience with it, I'm talking particularly about classic ASP.NET. Well, ASP.NET is such a poor abstraction that I still cannot understand how someone came up with this idea. The whole concept of WebForms is really far from what web is really about. How could they come up with a lifecycle like that: page lifecycle (click to see the picture). Honestly, how could anyone make such an unintuitive life cycle and say that it is easier for web programming because it's like WinForms programming?
Most ASP.NET developers think that ViewState and Session are perfectly good places for keeping variables responsible for page navigation. Yeah, it's so great when you click on a page and URL doesn't change. It's so easy to share content with other users. Crawlers also love it! And what is really cool, sometimes you have to debug your application to see what are your current arguments and then you may find out that e.g. you forgot to clear Session in some onclick event.
And the whole gridview thing. That's a neat idea. Take everything from any datasource you have (e.g. 10 million records from a database) and do all things like filtering, sorting, paging, etc. yourself! Furthermore, keep all data in ViewState.
Seriously, how could anyone come up with that?
Everybody knows that webpage is like a real desktop application and all actions should be seen as events, e.g. click. Everyone agrees? Great.
Templating engine? We will show how hard could that be. Even tags are messed up: inline tags.
Crossbrowser issues? Only in asp.net. Yeah, there are lots of controls that work in IE, but don't work in FireFox.
Someday, I will come back to asp.net issue. In this post I just wanted to show how crappy it is. In my opinion, when you write web apps in php, ruby or python, you feel that you're writing for the web. When you use ASP.NET, you're writing these stupid webforms.
To sum up, C# - great, ASP.NET - yuck.

And here comes the final conclusion.
If I had to write a web application that goes public (not some intranet application) I would choose...


... PHP + MVC. I'm really sure that the result would be far better using that technology.

If I had to choose a job and I could choose between using these two technologies I would choose...


... C# + ASP.NET. It's better paid and you have chances that you'll be writing some underlying layer in C# and you don't have to deal with ASP.NET.

I must check this ASP.NET MVC stuff. I hope it will solve all issues of classic ASP.NET.
Remember kids, choose the right tools for the job and keep in mind that all that glitters is not gold ;)
Q.E.D., Bitches!

środa, 19 sierpnia 2009

Prisoner of ice

All software companies talk about quality of their products. Quality is such a buzzword - sometimes I think that it doesn't mean anything at all.
However, quality means a lot to developers. Many developers that I know really care about products that they create, often against their managers and their companies. I understand when managers decide that they cannot spend more on some particular product, but I cannot understand a situation when a company makes developers work on some unimportant documents instead of making them focus on their work and implement the real thing.
I often encounter a situation when best developers in the team are assigned to create some specs in the early stages of development (often they have to analyze problems that they don't fully understand before the implementation), and people who are responsible for the actual implementation are unexperienced folks that have to learn how to solve problems during the project.
During the development everybody is in such a hurry that all tools and practices that are necesarry to create quality product are abandoned. This means no unit tests, no code reviews, etc. The project just flows. Because people who are developing it don't have any experience, they cannot solve even simple problems, they make obvious mistakes, copy code and everything becomes an awful mess. The project runs behind the schedule and, what is more important, it doesn't ensure any quality at all. After struggling with deployment, the product goes public and bugtracker is filled with bugs.
Unfortunately, because the budget was exceed, all funds are cut and people working on the project don't think about ways to heal it, but they start reading the specs, trying to persuade the client that the project meets specification requirements.
In this stage we can hear a bunch of silly questions, such as:
Do we have to log errors?
Do we have to support firefox?
Do we have to show error messages to users?
Do we have to validate input?

Well, the specs don't say anything about it. What's the conclusion? The project is just perfect. The only problem is that it just doesn't work.
After wasting lots of time on trying to vainly persuade the customer that it's not a bug, but it's a feature - the company faces the fact that they have to solve these problems. Unfortunately, as I've said before, they don't have any funds left. What is more, they discover that time spent on fixing the product generates loss, but if the developer does nothing or does not report his time on this particular product, no loss is generated. Now, the biggest issue is reporting the time spent on fixing the product. On paper it is better to sit and do nothing than to fix the damn thing.
It's like putting handcuffs on developers' hands. You just can't do anything. You know how to fix it, you have the idea, you know what you need, but you can't do it because, magically, the moment you report your time on the project, you start generating loss.
And the so story goes...

In my opinion, these problems are encountered in companies that are focused only on making money and they forget that they are making software. In the end, developers have to think about the budget and all that stuff around cost management, not about making great software. As the result, software is crappy and the income is far smaller than it was initially expected.
I have no experience running any company and maybe I am totally wrong, but I can tell bad software when I see one. And when I see developers that are prisoners of their projects, managers and procedures, I wish all project managers would be like Ron Jeffries or Joel Spoolsky. I wish developers could create applications that delight customers, create code that speak for them, have specifications consisting of test cases and work with the best programming teams in the world ;).

piątek, 14 sierpnia 2009

Unstoppable force meets immovable object

Code generation - here I come, once again.
Once upon a time I had to create a cms system. The system was quite large and I had to do it in about one month. What is more, the main reason I was creating the new system was to fix the issues we had with the old one. The point is that I had really not enough time.
However, I was able to create quite a decent application. I was rather satisfied with the result and the system didn't have a lot of code repetitions in its core.
Most of the logic was handled by business classes and they implemented good abstraction, i.e. versioning, cache and such stuff were implemented in base classes. However, the project had similar controllers and models (models in framework I used were something between a classic model and controller) for every module such as article, news, banner, etc. Due to a short deadline I was literally copying the files and changing names in them using replace function in IDE. Then, when I had some time to work on that code I changed all literal strings and other things specific to modules to constants that pointed to configuration in particular modules. My aim was to create classes that didn't force me to think while I was replacing text in source files, e.g. instead the sentence "Article has been added successfully" in template file I started using something like $moduleConfig[ARTICLE][TEXT_ADD_SUCCESS]. Well, that was my poor man's code generation. It had all the features of code generation besides the generator ;) At least I didn't have automatic code generation but I was manually copying files from other modules that were my templates.
To be honest, we've never encountered any serious problems with this approach and it worked quite well. However, I always thought that if I were given a week or so to work on this code and refactor it to extract base classes for models and controllers, the project would be so much better. The project was crippled with the fact that the whole code for these controller and model classes was duplicated. Unfortunately, I was never given the time to fix it before I left my ex-company. Everything was prepared, base classes should implement all the logic and child classes would know who they were and what constants they should use.
That story showed me that code generation, when used improperly, may seem an easy solution to a problem that should be addressed in another way.
Every tiny bit of logic that is generated shows that it should be placed in another element in design or higher in inheritance hierarchy.

First observation - IMHO, no application logic should be automatically generated.

But what about classes that give us strong typing for a cost of code generation? I'm not talking about typed DataSets in .NET because they suck so bad that they are not even worth mentioning but let's talk for example about classes generated from SubSonic. In the simplest approach generated classes reflect tables in database and they have strongly typed fields that represent columns in tables.
What are the advantages?
- you won't misspell a column in a table
- you also won't assign e.g. a string to an integer
But what are the disadvantages?
- you end up having lots of code that doesn't implement any logic at all
- every time you change database schema you need to regenerate your database classes
- if you generate CRUD from it, you will have problem achieving good level of code coverage
- if you change field name in database and want to keep property name in class, you may get confused using different names for same thing

Sometimes I think that we are paying too much for strong typing. Maybe the IDE should check the database and automagically check source code? For example, when I was writing a simple program in F#, the IDE checked if I specified correct format in literal string that was used in the method. When I specified in string representing format that I was expecting int and the corresponding argument was string, the IDE was smart enough to discover this problem. What is more, even if you misspell some fields you must have not tested the application at all if you didn't find this error.

Some frameworks let you write code that goes pretty well without the need to generate code (e.g. PHP frameworks); others (like ASP.NET that needs to see every control as a variable with a type, name and all that stuff) may try to force you to generate some code. Of course, I'm not a big fan of the latter.

And one final remark. I don't consider operations performed by a compiler to be code generation. Generated code may occur only in source files that developers are maintaining. We don't maintain byte code or low-level assembly instructions. The same goes with different forms of syntactic sugar that are handled by compiler and translated to "normal code" behind the scenes.
My friend wrote a note about on his blog: http://binary.freeperspective.net/countzero/2009/08/14/code-generators/. He says that he will come back to this issue. I'm eager to read his thoughts about the topic of code generation.