Friday, May 30, 2014

Settings: Giving your end user some control

It goes without saying, I've been working on a software project recently. This particular project was not simply a personal endeavor for the purpose of learning but a freelance job for a local organization. As it turns out, I found it crucial in this project to allow the end user (particularly those that would act as admin roles for it) to have various settings within the application, which differs greatly of course from an application I would write for myself. 

Software written for commercial purposes, in fact, tends always to have a slew of different settings that can be manipulated by the end user. The premise would seem to be that the developer knows not what the user wants specifically but has only a general idea. As I embarked on this project, I took what I had learned in software engineering courses that teach you to gather requirements, adapt to changes, and meet frequently with the customer as part of the software development lifecycle (SDLC) and applied it to my approach. In all of this, the goal was validation. Are we building the right software? Is this what the customer wants? 

One would imagine after the process geared toward constant/frequent validation was over we'd have tailored the system enough to exactly meet the customer's wishes. Why then, should I deem it necessary to include lots of settings?

Settings are a means to adapt to change even after the project is over. One of the settings I included in the project, for instance, was the URL of the client's webpage. Should this ever change in the future when I'm no longer working with the client, they should be able to make the adjustment for themselves, rather than hire a new developer. (Part of the system I built was a lite web browser that kept users within the domain of the client's website).

Settings satisfy a clientele who changes their mind often. I needed to include a setting for the length of time of inactivity on the software to return it to a default view. The client initially thought that 2 minutes was the appropriate length. He eventually changed it to 5, and then to 10. I said in one of the meetings, "How about I let you decide later in the admin interface?" Not surprisingly, that was perfectly agreeable to both parties.

Settings make the product personal. The application my team and I developed for our client was a kiosk application for a tablet connected to a large Samsung display. One of the settings included was what the default screen would say when no one was walking up and using it. I was initially told exactly what the client wanted it to say on that screen. However, I went ahead and included this as an option to be set by the admin if in the future he felt differently. A few prototypes down the road, our client was taking a swing at using it by himself without our guidance and one of the first things he did was take that title and make it his own.

My advice is, giving the end users options shouldn't be optional. Do it. Make the application as customizable as you can as long as it can't be changed so that it no longer serves its purpose. If a client is set on one specific "background color" for a GUI, for instance, it means you need to dust off that color chooser control and cram it in there. Chances are, your client will be ultimately more happy with the fact that he or she gets to choose the color any time he or she wishes versus realizing it doesn't quite look so hot anymore a few weeks down the road.

Thursday, May 29, 2014

Java Card Game Engine at a Glance

Not long ago, I decided to write a quick card game in Java. I wanted to write War because about a year prior, I had helped a friend of mine start learning Python for the first time and we wrote a War game together. Then recently, I started helping him again as he began to take on Java for a new job he scored. The incentive was here once again to write War, and would make for a great example of some basic Java usage/syntax. 

My project can be found on GitHub and is free to use: https://github.com/thedouglenz/JavaCardGameSystem/

I wanted to utilize as many object oriented programming tactics as I could, so I started designing and writing my models. The objects I wanted to capture and use from real-world card games were, of course, the idea of a card, a deck, a hand, a player, etc. I even ventured to create a class for a table, which encapsulated among other things, the number of sides of the game table for a given game. I added functionality to the deck such as dealHand and shuffleDeck. I gave every Player a Hand. Every Player the ability to play a card or a collection of cards on the table, the deck the ability to track and report its size, ...

In fact, it continued like that until I was realizing that by this time I was creating more than just the card game War. I had the whole domain model built for potentially lots and lots of card games. I could already sense the basic functionality was present for Crazy Eights, Rummy, Hearts, etc.

The aspiring user would simply have to take my layer of models and write most any game he or she desires by simply building an interface that controls game logic and some kind of GUI. Consequently, I wanted to try this for myself, which brought me back to War. I simply built a WarGUI class that utilized Java's Swing libraries to make the most basic GUI known to man, built a class, WarController, to control the game logic and a class, WarGame, that initialized everything the way I needed it. War obviously has a pretty standard and logically easy game loop. Nonetheless, the models served the purpose very well. 

Then my aforementioned friend asked if my system could be used to make poker. While I was tempted to say that it could, I knew that poker was a little bit different than the others. And a non-expert user would still have a lot of work to do if they wanted to use my system to invent a poker game. So I took to writing PokerHandEvaluator5Card. This is one of those classes justified by the general responsibility assignment software pattern (GRASP) known as "pure fabrication". Clearly, in real life there is no such thing as a "poker hand evaluator". Human beings are bright enough to do that work within minutes (or seconds) and dismiss it as trivial that they were able to do it. However, for the purposes of programming a dumb computer, a thing like evaluating a poker hand is a chore. Thusly, my implementation creates a new instance of my evaluator for each hand that needs it and exists thereafter only to report what poker hands are in it.

As you browse through my code and decide if and how you want to use it for your Java card game, feel free to make any additions/modifications. The state of the project at the time of this writing is "in progress" (in quotes because while I say its in progress, I haven't actually touched it in a while as I'm busy with other endeavors now, namely an Android application). Enjoy!

What do method signatures tell us?

A Java method signature
A significant aspect of object oriented programming is deciding what "objects" need to be designed, what data fields (or properties) they will have, and what behaviors (methods) are encapsulated within. For large projects, this usually starts on pencil and paper as opposed to in some IDE. One of the artifacts during what I like to call the "drawing board stage" is a class diagram. In the Unified Modeling Language, a class diagram is a structural representation of a system's classes and the relationships between them. Often, a class diagram will include listings of the properties (and their types) and methods (and their signatures) of a given class. UML is supposed to give us the means to design a system entirely before any code is truly written in a way such that anyone with the UML design plan can implement the system. Hence, the term "unified." 

So the question may arise, how much can we ascertain about the implementation of a particular aspect of a software system from a given method signature? What degree of ambiguity does it introduce to the implementation phase?

If you look at a method signature as it is represented in a UML class diagram, you can pick up the followings things: what class it belongs to, what it's name is, what its return type is, what its expected parameters are. For those who are reading this just to answer the title question, let's look at those individual pieces.

What class it belongs to
Keep in mind, you can garner this without having to look at a class diagram. It is obviously also apparent in the code itself. Say your colleague uses a tool that transforms a class diagram into a bunch of classes with their associated properties and method stubs to start you off with before you do the dirty work of actually coding. Clearly, the methods owner is still available to you. Is the class a hint to how the method should be implemented? Maybe so. A method called "speak" that belongs to a Dog class would probably indicate that the intention with "speak" was for the Dog object to bark, as opposed to what "speak" might do in a Cat class.

What its name is
Your biggest ambiguity buster is the method's name. For example, a method called "average" can usually be rightfully assumed to take an average of it's argument(s). However, a method called "fx98234kl" may do any sort of computation known to man.

What its return type is / what parameters it expects
Largely, the implementation of a function whose signature is the only clue you have is the input and output. Take a look at what parameters have been chosen as the input to the method and their names and types. Then examine the return type of the method. Then it becomes much like a physics problem for a student who hasn't studied. He or she may ask, "What are the starting units for this problem? What does the question tell me the ending units should be? What formula will get me there?" 

Often we can infer what is intended by a method signature from these 4 things. Say, for instance your colleague designs a class called Flight with a property, departureTime : Date that contains the method delayFlight(int minutes) : Date. What can we reasonably assume? 

We might decide that the method body should simply compute the Flight's departure time plus the number of minutes given in the argument and return that result. In a different company, someone does the following sighature: delayFlight(int minutes) : void. Suddenly, we are to write the function such that it computes the same result, but likely we are to set the class' instance variable departureTime right inside the method body.

To answer my title question, we can get a lot of concrete information from method signatures, and can even make some reasonable inferences. However, a method stub is a hole in the plan laid out by the use of UML. Filling the hole and making an ultimate complete design plan for a software system before code is written should include a similar plan at the modular level. A "unified pseudo-code," if you will might solve this problem.