The XMLocalizator Design Pattern

Starting with the example

XMLocalizator Design Pattern is crucial if you would like to use the XMLocalizator itself. So to have this aspect fully explained, let's start with a simple example which will be extending through this entire chapter. The example is very minimalistic and based on the fictitious GUI technology, so with a little effort you can transform it to the environment of Windows Forms, Windows Presentation Foundation, GTK#, etc.

Suppose that there is a window (deriving from WindowGui class) which displays two buttons (objects of ButtonGui class) and one label (as expected, an object of LabelGui class).

class ExampleWindow : WindowGui
{
	public ExampleWindow()
	{
		button1.Text = "Turn on the waiting mode";
		button2.Text = "Turn on the action mode";

		// and other assignments and method calls...
	}

	private void button1_Clicked()
	{
		label1.Text = "Waiting mode activated.";
	}

	private void button2_Clicked()
	{
		label1.Text = "Action mode activated";
	}

	private LabelGui label1;
	private ButtonGui button1;
	private ButtonGui button2;

	// and other suitable methods, properties and variables...
}

You can easily guess the destination of button1_Clicked and button2_Clicked methods. They change the visible text on the label1 control when the buttons are clicked.

Implementing ILocalizatorSubscriber

Localizator is able to work only with objects with implemented ILocalizatorSubscriber interface, so this point is important. The interface contains only one function in the simpliest possible format:

interface ILolicazatorSubscriber
{
    void Localize();
}

And below is the modified example:

class ExampleWindow : WindowGui, ILocalizatorSubscriber
{
	public ExampleWindow()
	{
		button1.Text = "Turn on the waiting mode";
		button2.Text = "Turn on the action mode";

		// and other assignments and method calls...
	}

	public void Localize()
	{
		// what to put here? 
		// keep reading this document...
	}

	private void button1_Clicked()
	{
		label1.Text = "Waiting mode activated.";
	}

	private void button2_Clicked()
	{
		label1.Text = "Action mode activated";
	}

	private LabelGui label1;
	private ButtonGui button1;
	private ButtonGui button2;

	// and other suitable methods, properties and variables...
}

From a purely technical point of view, the work is done and from this very moment you can subscribe this element to the Localizer. But practically, it will be doing completely nothing.

Building the Localize method

All things explained previously in this document are only a technical prelude of what is needed to do now. The truth is that to implement the XMLocalizator Design Pattern is to build the right Localize method. It's very important to understand what this function actuall does. Remember that:
  • Localize method examines the current state of the object and- basing on the gathered information- it puts localized phrases into their proper places.
Or in another words:
  • Localize can be executed at any time. And in that moment it should be able to
    • check which strings are visible
    • put the newly collected strings from Localizator to the controls
How to build it? At first, you must spot all places where are assignments of the text strings which are- no matter under what condition- going to be presented to the end-user. Checking the example line after line, here are the results:
  • button1.Text = "Turn on the waiting mode"; - in the constructor, text always visible on the button1 control
  • button2.Text = "Turn on the waiting mode"; - in the constructor, text always visible on the button2 control
  • label1.Text = "Waiting mode activated."; - in the button1_Clicked function, text visible if button1 has been clicked
  • label1.Text = "Action mode activated."; - in the button2_Clicked function, text visible if button2 has been clicked

How to put these lines into the Localize method without changing anything that is visible from the outside world? Well... use your imagination and experience, because there a plenty of solutions. In this example it's an additional variable that keeps information whether the action mode is activated or not. Here, take a look:

class ExampleWindow : WindowGui, ILocalizatorSubscriber
{
	public ExampleWindow()
	{
		actionMode = false;

		// and other assignments and method calls...

		Localize();
	}

	// all assignments of the end-user visible texts are in here
	public void Localize()
	{
		button1.Text = "Turn on the waiting mode";
		button2.Text = "Turn on the action mode";

		if (actionMode == true)
		{
			label1.Text = "Action mode activated";
		}
		else
		{
			label1.Text = "Waiting mode activated";
		}
	}	

	private void button1_Clicked()
	{
		actionMode = true;
		label1.Text = "Waiting mode activated";
	}

	private void button2_Clicked()
	{
		actionMode = false;
		label1.Text = "Action mode activated";
	}

	private bool actionMode;

	private LabelGui label1;
	private ButtonGui button1;
	private ButtonGui button2;

	// and other suitable methods, properties and variables...
}
Look at the constructor. The Localize method is called after all other operations; ready to place texts into the controls. The whole operation relies not exactly on moving every line with string assignment to one method. Check out the button1_Clicked and button1_Clicked functions; there is the additional line that changes the actionMode's value, but rest of the code is untouched. As you know from How it works? chapter, when you command the language change, Localizator runs the Localize method and at that moment, all visible phrases need to be reassigned correctly. But in these two functions only one modification is taking place. Of course, something like this:

private void button2_Clicked()
{
	actionMode == false;
	Localize();
}
is 100% correct, but in large applications with huge amount of text - it will be a great exaggeration.

Now, the XMLocalizator Design Pattern is revealed and explained. The code below is the final version of the example, but to fully understand it, you have to read the How it works? and Using Localizator chapters. If you haven't done this yet, know this simple explanation that loc["Some text"] is taking the "Some text" phraze, but localized to the actually selected language. How to obtain the loc object and choose the destination language? As mentioned, it's all in here.

class ExampleWindow : WindowGui, ILocalizatorSubscriber
{
	public ExampleWindow()
	{
		actionMode = false;

		Localize();

		// and other assignments and method calls...
	}

	// all assignments of the end-user visible text are in here
	public void Localize()
	{
		button1.Text = loc["Turn on the waiting mode"];
		button2.Text = loc["Turn on the action mode"];

		if (actionMode == true)
		{
			label1.Text = loc["Action mode activated"];
		}
		else
		{
			label1.Text = loc["Waiting mode activated"];
		}
	}	

	private void button1_Clicked()
	{
		actionMode == true;
		label1.Text = loc["Waiting mode activated"];
	}

	private void button2_Clicked()
	{
		actionMode == false;
		label1.Text = loc["Action mode activated"];
	}

	private bool actionMode;

	private LabelGui label1;
	private ButtonGui button1;
	private ButtonGui button2;

	// and other suitable methods, properties and variables...
}

Last edited Mar 21, 2011 at 6:35 PM by bartoszlenar, version 18

Comments

No comments yet.