Thursday, December 27, 2007

2008: Some thoughts on going virtual

One of the goals for me in 2008 is to bring my production environment over to a virtual machine. 

That should give the following benefits:
1. Complete installations can be backed up, so if a future update fails, it is easy to step back in time. (Less downtime)
2. It is easy to make multiple backups, with multiple states of the installation.
3. It is easy to take you complete production environment with you.
4. More flexible for setting up new software without hurting your existing software. (Testing new technologies etc.)

The benefits are clear, more secure, less downtime in case of an event, and more flexible.
First question that comes to mind thinking about going virtual is:

How to set up a VM environment as efficient as possible?

The answer to this question is, of course, specific for each situation. Because I have never done this, I will share with you how I think about settings things up. If you have any tips, please step in!

I use, the two major IDE's in the market today, for my development, namely CodeGear RAD Studio and Microsoft Visual Studio. The latter is for .NET development only, and mostly ASP.NET development.
So I think about setting up two seperate VM's: (They will be based on Windows XP pro)

1. Delphi VM
- Delphi 7 (for older projects)
- BDS 2006 (.NET personality for Winforms .NET 1.1 development)
- RAD Studio 2007
- Delphi third party components
- Visual SourceSafe for version control

2. Visual Studio VM
- Visual Studio 2005 (Winforms/ASP.NET developement)
- Visual Studio 2008 (future...)
- Third party components
- Visual SourceSafe for version control

On each VM I completely install all necessary software and components. After that I will backup those VM's as the basic production environment setups. With each future update (IDE, components), I will update those basic environments also, keeping them up-to-date. If an update fails there is no problem, just use the last backed up clean environment.

The source code and SourceSafe
On the hosting machine, my laptop by default, I will install all other necessary applications, like Microsoft SQL Server, Office etcetera.
I will keep my application source codes located on the hosting machine, which I can reach in my VM through shared folders. Doing this, I can backup them as usual. With Visual SourceSafe in VM, I can check out files on my laptop, and alter them within the VM.

Well just some thoughts about setting up a development VM.

Happy new year!!

Tuesday, December 18, 2007

RAD Studio 2007 December update released!

CodeGear just released the December update for RAD Studio 2007, as well as the update for Delphi 2007 and C++ Builder 2007.

Looks like there are a lot of fixes.
284 Core bugfixes
93 Delphi 2007 fixes
46 C++ Builder fixes
157 Delphi 2007 .NET fixes

According Nick Hodges blogpost about the upgrade it should not be a too long update this time. Because of the fact that it is a binary update, all unofficial patches that were applied should be uninstalled.

Chris Pattinson looks back at 2007, from a QA stand point of view, in his blogpost CodeGear Quality Review 2007. 7006 defects are fixed since 1 january 2007!

You can download the update at the registered users download page. Or check for updates within the IDE.

Monday, December 17, 2007

Programming in Delphi sins #3

In this serie I will tell you, what we find a sin, in Delphi programming.

Using published properties of components from another class
When you place components on forms and datamodules in Delphi they are published by default. In other words you can use components in your form that belong to other forms/datamodules. If you do this, those forms will be tightly coupled and therefor this is not quite a good OOP practice.

type
TdmMain
= class(TDataModule)
//These components are published and direct
// accesable by other forms/datamodules
SomeDataSet: TADOTable;
adsAnotherDataSet: TADODataSet;
private
{ Private declarations }
public
{ Public declarations }
end;

Suppose you have a form that uses a datamodule with some dataset on it and you want to show some field value in a label on your form. You could do it like this:


procedure TForm3.SetCaption;
begin
SomeLabel.Caption :
=
dmMain.SomeDataSet.FieldByName(
'SomeField').AsString;
end;


This is bad practice. Suppose that, something simple as the name of the field changes, you would have change both your datamodule, and your form.

Solution:

Use properties and functions (getters), not properties from published components.

In the datamodule:
property SomField : string read GetSomeField;
procedure TdmMain.GetSomeField : String;
begin
Result :
=
SomeDataSet.FieldByName(
'SomeField').AsString;
end;

In your form:
procedure TForm3.SetCaption;
begin
SomeLabel.Caption :
= dmMain.SomeField;
end;

A more dramatic way to avoid use of published properties is to move all published properties into the private section of the class.

This gives you best practice, however if you use dataware controls, you then should couple them manually.

So for the sake of dataware controls we keep them published, but always write properties or getter functions to get values in code.

Tuesday, December 11, 2007

Programming in Delphi sins #2

In the first episode of this serie I talked about avoiding the default auto-create function for forms and datamodules in Delphi.
As Zarko Gajic (delphi.about.com) pointed out in the comments I made another sin ;-) in the example code. Always something to learn! Thanks for the tip Zarko!

Well here it goes #2:

Never use a owner if you create a component/form yourself and free it instantly
So don't do this: TForm3.Create(self);

procedure TForm5.Button1Click(Sender: TObject);
var
MyForm : TForm3;
begin
MyForm :
= TForm3.Create(self);
try
MyForm.ShowModal;
finally
MyForm.Free;
end;
end;

But do this: TForm3.Create(nil);


procedure TForm5.Button1Click(Sender: TObject);
var
MyForm : TForm3;
begin
MyForm :
= TForm3.Create(nil);
try
MyForm.ShowModal;
finally
MyForm.Free;
end;
end;


If you pass self (in this case Form5) as the owner you rely on Form5 to free it when form5 is destroyed. Beside maintenance confusion it also has a backdraft on performance.

Zarko has a great article on this:

A warning on dynamically instantiating components

Always great to learn something new!

Monday, December 10, 2007

Programming in Delphi sins #1

In this serie I will tell you, what we find a sin, in Delphi programming.

Using auto create forms and datamodules
Standard Delphi will create automatically all forms and datamodules for you. This gives you a headstart when you are first learning Delphi, but in the end it will give you a headache!

Sooner or later you begin to wonder where that 'Form1' object is coming from. (It is in fact a variable in the interface section of his own unit)
Other issues:

  1. Your program becomes slower, consuming more memory then needed with many forms created.
  2. Bugs will be harder to track, because you just can not know the state of all your forms and datamodules. Code could run, without you knowing about it.

Solution:
Turn off auto creation of forms
in the options Dialog-VCL Designer tab, and create your forms/datamodules when you need them, and free it when you are done with it. In existing projects remove those forms from the auto create forms list in the project options.

Create a form when you need it, using your own variable:

procedure TForm5.Button1Click(Sender: TObject);
var
MyForm : TForm3;
begin
MyForm :
= TForm3.Create(self);
try
MyForm.ShowModal;
finally
MyForm.Free;
end;
end;

Remove the 'global' var in unit of the newly created forms and datamodules, you just don't need them:


unit Unit3;

interface

uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms, Dialogs;

type
TForm3
= class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

//Remove this global var, which is
//the instance that is created with
//the auto create forms option turned on
var
Form3: TForm3;
//--

implementation

{$R
*.dfm}

end.

Use an image as your UIBarButtonItem

Using an image as your UIBarButtonItem in your navigationcontroller bar can only be achieved by using a common UIButton as the BarButtonItem...