Lesson 04.5: Improving the World – Factory and Guard Clauses

In this lesson, we will do more refactoring to the code we wrote over the last few lessons, where we were building the world classes.

 

 

Named Parameters

In the GameSession constructor, we instantiate a Player object, and set its properties.

Because the Player class has public properties, that each have a public “set”, we can make this code cleaner, by using “named parameters”.

When we use named parameters, we can remove the parentheses after the class name, when we instantiate the object. Then, we add opening and closing curly braces. Inside the curly braces, Visual Studio will show us the public properties that we can assign values to. We add the property name, an equal sign, and the value we want to assign to the property. If we want to add values for more than one property, we need to add a comma between each property.

 

Step 1: Edit GameSession.cs

In the constructor, replace this code:

 

With this code:

 

I like this technique because it is very clear what properties are being set. Plus, IntelliSense is available, as you set the property values.

 

Static Factory Class

While we are inside the GameSession constructor, we can make an improvement to the WorldFactory class.

Notice that we instantiate a WorldFactory object, get a World object from the CreateWorld function, and never use the WorldFactory object again.

We can make a change that will allow us to get a World object from the WorldFactory class, without instantiating a WorldFactory object. We do this by making the WorldFactory “static”.

You can use a static class, without instantiating it. Because we are only going to use the WorldFactory class to create a World object, it is a good class to make static. Using a static class, or function, to create objects is known as the Factory Design Pattern.

There are some rules to remember about static things.

  1. A static class can only have static methods/functions.
  2. An instanced class (like the Player class) can have static functions. These functions can be called, without creating an instance of the class.
  3. A static function can only use objects it creates inside the function, other static functions, or static class-level variables.

 

 

Step 1: Edit WorldFactory.cs

Change this line:

To this:

 

Notice that the CreateWorld function now has red squiggly lines underneath it. If you hover over CreateWorld, you’ll see an error message that says:

‘CreateWorld’: cannot declare instance members in a static class

Static class ‘Engine.Factories.WorldFactory’ cannot have a non-static method ‘World CreateWorld()’

 

This error is saying, “because the WorldFactory class is static (it will never be instantiated), it cannot have a function that requires an instantiated object”.

To fix this, we will also make the CreateWorld function static, by changing it to this:

 

Now, if we look at the constructor in GameSession, we see some errors. That’s because we are trying to instantiate a WorldFactory object – which we cannot do, now that it is a static class.

So, we will change these lines:

To this:

 

Now, the program doesn’t create an object it will only use one time.

 

NOTE: We can safely make WorldFactory a static class because we are not “maintaining state” in it – we are not holding any variable values inside the static class. We cannot make the Player class static because we need to “maintain state”. In a Player object, we store the player’s hit points, experience points, gold, etc. Those values will change, as the user plays the game.

You can store values in a static class, by creating static variables (like the private variables we use in the Player class). However, then you need to be more cautious about what changes those values. Because a static class does not need to be instantiated, it is available everywhere in the program. When any part of a program can change a value, it can be difficult to track down bugs.

 

Guard Clauses

Finally, we will look at the movement functions in GameSession.cs.

Currently, MoveNorth (and the other movement functions) will always try to move the player – even if the world does not have a location in the direction of the function. We prevent that from happening by making the movement buttons invisible in the UI. However, there is a saying in programming, “Never trust user input”. In some programs, a hacker could figure out how to send invalid calls to our code. Even though this is not a commercial program, we should be safer.

Inside each of the movement functions, we will do a check if there is a location in the direction. If so, we will set the CurrentLocation to the new location. If not, we will not do anything.

So, we will change the code for the movement functions to this:

 

Now, if the movement button visibility does not work, we have a second layer of protection in our code – which should prevent the user from doing something that would cause an error.

 

 

Final Version of the Source Code

WorldFactory.cs

 

GameSession.cs

 

 

 

 

Return to main page

2 thoughts on “Lesson 04.5: Improving the World – Factory and Guard Clauses

    1. I normally add two lessons per month. In April, I had a large project and also went on vacation. So, I didn’t have any new lessons. I should be back to the regular schedule, with a new lesson this weekend.

Leave a Reply

Your email address will not be published. Required fields are marked *