How to make your internal classes accessible to your unit tests in .NET

27 07 2009

Here a little tip I’ve found while reading Moq source code. If you want to test some internal classes of your library, you don’t have to make your classes public in order to be visible in your test assembly (like how I was doing untill now…)

The trick is to add this little line into your assembly properties (AssemblyInfo.cs)

[assembly: InternalsVisibleTo("NameOfYourTestAssembly")]

Now all class with the internal visibility will be accessible to your unit tests. For private visibility, one solution is to use reflection or just look on Google 😉





Refactoring game legacy code: Part 1 – Introduction

26 07 2009

Introduction

Hello, welcome to my series of article about refactoring game legacy code. Game legacy code is no different than other types of code. What’s makes game different than others type of codes ? With a game, you are dealing with a event driven, simulated real-time architecture. They have different needs and requirements than a business, Web or rich client application. Games need to react fast to events such as ‘gun was triggered’, you have parts of your code that are called 30 or 60 times per second, loading times need to be short, etc.

There is a lot of things going on in a game, where in a typical business application you just need to collect some input, process it and persist into a database (good ‘ol CRUD).

The subject

The subject is my first complete game ever written. If you look at the projects sections of this site, you’ll see some failed attempts. The game is a Tetris clone called “That Game From Russia (you know it)”. It is written in C++ using SDL library. It was done in two weeks back in January 2009. If you have read my article Paradigm Shift, you know this was before I read many books and articles that changed my way of thinking about code, design and architecture.

The code can be found at http://code.google.com/p/gamefromrussia/

We start with SVN revision 5.

Current state of the architecture

The architecture is based on a basic state machine. There is a bit of duplicated code scattered around the code, like the input handling. The code is pretty tightly coupled. They are little to no abstraction in the code. SDL types are found in public API. When I created the code, I intended to do my Tetris in one day. Yeah silly I know. I didn’t intend to create a flexible architecture. I wanted to create a Tetris for fun thus I didn’t try to care that much about the craft of my code.

Anyway so you have the states (DropPiece, InitGame, Setup, GameOver, RemoveLines, SetNextPiece, PauseState, LinesRemoveAnimation) that define the core behavior of the game. Each state has a enter(), execute() and exit() methods. enter() initialize the state, execute() is called on every iteration of the game loop and exit() is called before changing to another state.

The “domain” or the core of the game are in the classes Block, BlockLine, Board, Piece. Block is a single block. BlockLine is a line of blocks in the Board. Board contains a list of block lines. Piece is a collection of blocks that represent the shapes in a Tetris game.

The other classes are support classes. SoundPlayer manages sound effects and music. TextPrinter manage drawing the current level, the score and the number of lines.

What we are trying to refactor ?

What I want to refactor is all the code related to the Piece handling. I want to make the rotation code easier to understand. Currently, for each type of piece, you have obscure code that move the blocs depending of the direction. It assume that the x, y is for the center block and the other blocks are moving according to this block. While developing this code, I had sketches on paper to help me map the blocks for each piece. I shouldn’t needed a piece of paper to manage the complexity of this code.

The right way to rotate a piece is to use a rotation matrix and apply it to each of the blocks coordinate. I found this when looking at other Tetris clone code. You don’t need to use a matrix explicitly thought. I will explain the solution a little deeper in a following article.

When you refactor code, you should keep in mind your main goal. When dealing with legacy code, you can be tempted to do large scale refactoring of your ugly, stupid code. Having a goal help you focus of refactoring code that matters for what you are trying to accomplish.

Why I am doing this ?

In this case, I want to train my refactoring, TDD, SOLID skills in a C++ code base in preparation for a much larger game project this fall. Also, I am to experiment some techniques illustrated in Michael C. Feathers book Working Effectively with Legacy Code.

Refactoring legacy code is hard

I don’t claim to be an expert in refactoring legacy code. In fact, it’s quite the opposite. I am still a beginner in refactoring legacy code. Up to this point, I only refactored one legacy code base I written in C# back in 2007. It is quite a hard journey depending of the quality of the code base. My current code base has a lot of inner, subtle dependencies that we will need to break over time.

Next episode

In next episode, we’ll start doing some code cleanups to get a feel of the code base before setting up the tests in preparation for larger refactorings.





Paradigm Shift

1 06 2009

This title sums up pretty well the last school year for me. I changed a lot of things in my programming(geek ?) life that I need to write a whole post about it.

First of all, I used to be a Linux user AND developer (for KDE) all the way. I used Linux primely on my desktop and my laptop. I used to be a KDE contributor until University took all my time. Up to that point, I managed to do all my stuff in Linux except for certain things that really required Visual Studio or a Windows-only program. Now I need Visual Studio more than ever, and since I was tired to swag my girlfriend’s laptop every time I needed Windows, I wiped out my Mac partition and installed Windows Vista. Oh the horror some might say, but nowadays I’m been using Windows 7 RC and there were much rejoicing. I haven’t felt the need to restore GRUB on my laptop and suspend-to-RAM is painless.

The seed that started this whole shift is when I was working on my summer work and I grew tired of writing the same CRUD database stuff and business rules. From this day, I decided that I needed something more challenging. Fortunately I was in the good curriculum, only my future goal changed.

Then I (re)found gaming. I thought games would be the challenge I was looking for.

When I started university, I have no intention to become a game developer, I didn’t play game that much for several years where in my young years I used to be a Nintendo freak. My goal when leaving University was to join a open source company to work on free software or find something that wasn’t related to IT(not custom apps for biz) or gaming. Now, I want to join a game company or maybe form my own with friends, time will tell.

Back to open source. Like I said, I was a big Linux user. I still think they are cool stuff in Linux and open source is nice. I still use a lot of free software. But the reality as a developer is slapping me back to the face. The fact is Windows is the dominant platform and if you want to get the most users, either you go the Web approach (which I kinda dislike) or you develop for Windows. Also, I want to be a game developer and Windows is THE platform for developing games no matter the target platform.

Beside my switch in careers goals, I also change a lot my mentality. Since the last months I’ve been reading a lot of books about software practices such a Clean Code, Agile Patterns Principles and Practices, Refactoring, Code Complete. I also read a lot of articles from Joel on Software. I might say that I got influenced a lot by those articles and that changed my way of thinkings about software.

Lots of changes. Lots of contracting ideas that I need to sort out and came out with the mixture that will work for me.





API simplicity and design

14 06 2006

I just ported Kopete to new KDialog API and to new KPageDialog, which was done by Tobias Koenig last week. The new API is really nicer to use, you have done a great job Tobias and this helped me to adapt a lot of old code.

This new API use a philosophy called “Write once, read multiple of times.”, I use the same philosophy for some time while doing libpapillon. I will give you a case, when you read a constructor like this new KDialog(i18n("Caption"),parent, name, User1 | User2, User1, true, ...). This make sense when you first write it because you have the API documentation open in another window. Now, re-read this code 1 month later, the code will make less much sense and you will need to remember and try to guess what each parameter do. By simplicifing your API, you make your code more readable and more maintainable, not just for you but for yours followers too because we are in open source world and other people read our code.
Updated code:

KDialog *newDialog =new KDialog(parent);
newDialog->setCaption( i18n("Caption") );
newDialog->setButtons( KDialog::User1 | KDialog::User2 );
newDialog->setDefaultButton( KDialog::User1 );

Easier to read isn’t ? 🙂

Another philosophy should be used while designing API is make your interface ease to use and harder to misuse. In fact, that’s one item from book “Effective C++ 3rd Edition.”. Every serious C++ Programmer should have a copy of this book IMO. The goal is to reduce the complexity of your API to avoid confusion when using it, thus avoiding bugs and unexpected behavior. Also to report error at compile-time and not at runtime. I will reuse the example from the book (that I paste from my memory ;)).

Here a simple encapsulation of a Date.

class Date
{
public:
Date(int year, int month, int day);
};

What happen if someone call Date(21, 02, 1986) or Date(02, 21, 1986) ? This can lead to an unexpected behavior.

Here a good way to encapsulate Date:

struct Month
{
explicit Month(int);
};
struct Day
{
explicit Day(int);
};
struct Year
{
explicit Year(int);
};
class Date
{
public:
explicit Date(Day day, Month month, Year year);
};

By making use of keyword explicit, you avoid implicit conversion to int and compiler will generate an error if you try to use the wrong date component.