Pages

Showing posts with label Dev best practices. Show all posts
Showing posts with label Dev best practices. Show all posts

Friday, November 7, 2014

Java Game Development - Part 1: Developing a single user game using strategy design pattern

Introduction


The Game

The lost fish is a simple educational game for children to learn about behaviors and characteristics of different sea creatures such as fishes and plants in a fun and challenging way.

E.g., Dolphin is an innocent, friendly sea animal, whereas shark is harmful

Also, it is intended to make the children aware of common characteristics of the sea creatures, which belongs to a particular category.

E.g., harmful animals will scream furiously and look angry

In this game, player is a baby fish that has lost in the sea. Baby fish has to find its way home passing different barriers, while escaping from harmful animals.

Game Rules


Assume, before starting the game, baby fish will be given some knowledge on the sea creatures by its mother fish. But, mother fish will not be able to tell about “all” the sea creatures.

If the baby fish collides with a harmful creature, the baby fish will get weak. (Loose energy)

If the baby fish identifies and meet friendly fish it will gain energy. If energy level is below zero, baby fish will die and the game is over.

Baby fish will get bonus points if it reach/find home soon.

Win the Game


Baby fish has to reach home with maximum energy level with maximum bonus points, to win the game.

Design

This game is designed with the intention of improving further with a variety of sea animals with different appearances and behaviors. Then, game will keep the players interested and also this will lead to a good learning resource as well.

Design Decisions

OOP concepts such as encapsulation, inheritance and polymorphism are used to improve the reusability, maintainability and the extendibility of the game.

 Strategy Design Pattern

Strategy design pattern is used to effectively extend the game with new sea creatures with diverse behaviors, to keep the player entertained. Also, different behaviors can be dynamically invoked using this approach.

An example scenario is given below:

Assume we have to add two new sea animals (E.g., whale and jelly fish) with different/ existing sound behaviors to the game, with out doing major changes to the core game design and avoiding duplicate code. If we use the traditional inheritance approach, where all the sea animal behaviors (E.g., sound/ scream) inherit from parent class SeaAnimal, then the code will be duplicated for similar behaviors. But, the given approach will solve that problem using interface implementations for similar behaviors.

The current design supports the above scenario in two different ways.
•    Inheritance: New sea creatures can be created by extending “SeaAnimal” abstract class
•    Polymorphism: Novel sound behaviors can be added or existing sound behaviors can be reused using “Sound” interface.

Using Constants

Constant values are used wherever applicable to improve reusability and maintainability.

Class Diagram


Sequence diagrams






 UI Design


Here's the video: https://www.youtube.com/watch?v=ipv_6yYAUw4

References

[1] http://obviam.net/index.php/design-in-game-entities-object-composition-strategies-part-1/
-->



Wednesday, April 2, 2014

How would you decide if a class should be abstract class or interface?

It depends :)

In my opinion, to implement methods in abstract class you need to inherit the abstract class.One of the key benefits of inheritance is to minimise the amount of duplicate code by implement common functionalities in parent classes. so if the abstract class have some common generic behaviour that can be shared with its concrete classes, then using abstract class would be optimal.

However, if all methods are abstract and those methods do not represent any unique/significant behaviour related to  the class instances, it may be better to use interface instead.

Use abstract classes to define planned inheritance hierarchies. Classes with already defined inheritance hierarchy can extend their behavior in terms of the “roles” they can play, which are not common to its parents all the other children, using interfaces. Abstract classes will not help in this situation because of multiple inheritance restriction in  java language.

How interfaces avoid “Deadly Diamond of Death” problem?

A key difference between interface and abstract class is, “Interfaces simulate multiple inheritance” for languages where multiple inheritance is not supported due to “Deadly Diamond of Death” problem.

How interfaces avoid “Deadly Diamond of Death” problem?

Since interface methods do not have their underlying implementation, unlike the inherited class methods, there won’t be this problem as there can be multiple method signatures that are same, but there can be only one implementation for a particular class instance as duplicate methods cannot be compiled without any errors.

Reference:
Head First Java

Sunday, February 2, 2014

Better approach to load resources using relative paths in Java

FileInputStream (Absolute path)


To load a resource file such as x.properties for program use, first thing that we would consider will be specifying the absolute file path as given below:

InputStream input = new FileInputStream("/Users/jwithanawasam/some_dir/src/main/resources/
config.properties”);

However, when ever we moved the project to another location, this path has to be changed, which is not acceptable.

FileInputStream (Relative path)


So, the next option would be to use the relative file path as given below, instead of giving absolute file path:

InputStream input = new FileInputStream("src/main/resources/config.properties”);

This approach seems to solve the above mentioned concern.

However, problem with this is the relative path is depending on the current working directory, which JVM is started. In this scenario, it is "/Users/jwithanawasam/some_dir". But, in a different deployment setting this may change, which leads to change the given relative path accordingly. Moreover, we, as developers do not have much control over JVMs current working directory.


In any of the above cases, we will get java.io.FileNotFoundException error, which is a familiar exception for most java developers.


class.getResourceAsStream


At runtime, JVM checks the class path to locate any user defined  classes and packages. (In Maven, build artifacts and dependancies are stored under path given for M2_REPO class path variable. E.g., /Users/jwithanawasam/.m2/repository) The .jar file which is the deployable unit of the project will be located here.

JVM uses class loader to load java libraries specified in class path.

So, best thing we can do is load the resource specifying a path relative to its class path using class loader. Here, specified relative path will work  irrespective of the actual disk location the package is deployed.

Following methods reads the file using class loader.

InputStream input = Test.class.getResourceAsStream("/config.properties");

Usually, in Java projects resources such as configuration files, images etc. are located in src/main/resources/ path. So, if we add a resource immediately inside this folder, during packaging, the file will be located in the immediate folder in .jar file.

We can verify this using the following command to extract content of jar file:

jar xf someproject.jar

If you place the resources in another sub folder, then you have to specify the path relative to src/main/resources/ path.

So, using this approach we can load resources using relative paths in a hard disk location independent manner. Once we package the application, it is ready to be deployed anywhere, as it it is, without the overhead of having to validate resource file paths, thus improving the portability of the application.

ServletContext.getResourceAsStream for web applications


For web applications, use the following method:

ServletContext context = getServletContext();
    InputStream is = context.getResourceAsStream("/filename.txt");
 
Here, file path is taken relative to your web application folder. (The unzipped version of the .war file)
E.g., mywebapplication.war (unzipped) will have a hierarchy similar to the following.  
 
mywebapplication
    META-INF
    WEB-INF
        classes
   filename.txt
 
So, "/" means the root of this web application folder.  
This method allows servlet containers to make a resource available to a servlet from any location, without using a class loader. 


 

Tuesday, October 9, 2012

Difference between "override" and "new" keyword

"New" modifier is used to hide a member inherited from a parent class which is not virtual. This does not have the polymorphic behavior, so if someone calls the parent class method, the implementation in the method which "new" modifier has been used is not been called.

"Override" modifier can be used to override virtual or abstract members and it contains the polymorphic behavior.

Wednesday, August 22, 2012

SourceMonitor for code metrics

http://www.campwoodsw.com/sourcemonitor.html

Following information can be retrieved in your source code:
  • No. of files
  • No. of lines
  • No. of statements
  • % of comments
  • % of docs
  • Classes
  • Max complexity
  • Max depth
  • Avg. depth
  • Avg complexity

If you are using a source control mechanism such as Perforce, then you can get the changes for each time period or revision. This is significantly fast also.


Wednesday, February 29, 2012

Nested IF conditions vs Single line IF with AND operation

In C#, compiler will generate the same MSIL code for following code chunks.

Single line IF

if ( A && B ){
  // Do something;
}

Nested IF

if ( A ){
  if ( B ) {
  // Do something;
  }
}

Tuesday, September 13, 2011

Does StringBuilder always better than String in string concatenation?

No.

Why?

Use StringBuilder if you are creating a long string using a loop, when the number of string are high.
Do not use StringBuilder for small number of strings becuase, it makes the code less manageable and StringBuilder contains more logic than string, when it comes to processing the string.

Monday, September 12, 2011

Avoid using unnecessary objects

Why?
  • It is NEVER free.
  • To avoid unnecessary memory allocation
  • Avoid frequent garbage collection

Thursday, September 8, 2011

Circular dependancies in Visual Studio

If you add project A as a reference in project B, you can't add project B as a reference in project A if both projects are in same solution.
Because, Visual Studio explicitly disable circular dependancies among projects in a solution.


Error you get when you create a circular dependancy in a Visual Studio solution

It is a bad practice to allow circular dependancies between .dlls, because in the above scenario, if you change A you need to rebuild B and since B is changed you need to rebuild A and vise versa, thus creating an infinite loop which can cause a memory leak in the server.

Tuesday, August 23, 2011

Why you should not set an extreme value as server time-out?

Time out value is there to limit the amount of processing time allocated for requests. If you assign a larger value as time out, it will stay more time in the queue. So, even though you can always get over from a time out issue by increasing the time out value, ideally what needs to be done is ensure that your application is well optimized so that it will execute within less duration than the specified time out value. It will enhance the server performance.

Dev best practices: Meaningful variable names

Always learn to use meaningful and more descriptive variable names.
Ex: Do not use "arr" to name an Array, use "itemCollection" instead!