The Software Purist |

CAT | Actionscript

Dec/09

6

Programming Paradigms

If you’re an experienced programmer, this probably won’t be new information, but I hope to at least present it in a new way.  When developing software programs, there’s different ways to think about the problems you’re trying to solve, which affect the entire process from initial design to how it’s coded, even to how it’s tested.  I discuss a few of these in this article.

Unstructured

These days, unstructured styles of programming are generally frowned upon. In the old days, you might have programmed unstructured in older dialects of Fortran, COBOL, Basic, etc…, and used GOTO to move between sections of code. All variables were global to the program and so you had to be very careful about the usage and naming. This type of code was simple to code at first, but very difficult to read. In addition, it didn’t scale well at all. As programs got larger, it became exponentially more difficult to maintain. There isn’t much to talk about here, because coding in this manner is rare nowadays, except in specialized fields. You can imagine a program looking very sequential, though. Something like this:

if my height is less than 4'
goto short
elif my height is greater than 6'
goto tall
else
goto normal

short:
print "You are too short to go on this ride"
tall:
print "You must wear a helmet."
... offer helmet ...
if accept
goto getonride
else
print "No dice..."
normal:
goto getonride

getonride:
print "Welcome onto the ride."

exit:
print "You must leave.  NOW!"

As you can see, this can quickly get out of control. Reuse was almost non-existent.

Procedural Programming/Imperative Programming

Procedural programming was the first type of structured programming and it started to become widespread in the late 60s and early 70s.  It was probably the first major step towards programming we do today.  Structured programming is still used quite a bit and is the basis for some of the later programming paradigms.  Structural programming is responsible for mostly eliminating the widespread use of GOTO.  This methodology was more commonly taught at the time I was in college, as Object-Oriented programming was newer at the time, and not very well understood outside of a smaller community.  The main concepts behind is that any task can be broken up into sub-tasks.  Emphasis is placed on functionality and data structures.  With this, it is became easy to break down a workflow with direct relationships and traceability for a functional specification, often, provided by a customer.  This directly can be derived into software functional requirements, and then directly derived into software code, and then directly derives into tests.  Because all of the emphasis is on functionality, and the code is structured in that manner, it provides a lower barrier to entry than newer techniques such as Object-Oriented Programming. Due to this, the common tool for figuring out where a piece of code is implemented is simply a matter of using grep (on Linux/Unix) or find (on Windows).  Data definitions can be provided by systems engineers, because once the functionality is defined, the data required is also easily derived.

Some of the common procedural-oriented programming languages are Ada-83, Algol, Pascal and C.  Of course, at different points, many of the procedural programming languages later gained Object-Oriented features with new revisions (Ada-95, C++, etc…).  One of the main problem with structural programming concerns reuse.  You can successfully meet functional requirements, but later notice that different components of the system have 95% similar functionality.  It becomes difficult to directly express these relationships in your code.  To try to handle reuse of sections of code where there can be different types used, you wind up with large if and/or switch statements.  The problem then becomes that for each new type that supports this relationship, you wind up modifying working code, which is always risky.  Modifying working code makes it difficult to supply a working library because elements in the library will often be changed.

As an example, let’s take the case of a vehicle and then provide multiple types of vehicles, a car and a bus. Example in C:

void drive(int type, void* obj)
{
	switch (type)
	{
		case CAR:
		{
			Car* car = (Car*)obj;
			// ... Logic to accelerate car
		} break;
		case BUS:
		{
			Bus* bus = (Bus*)obj;
			// ... Logic to accelerate bus
		} break;
		default:
		{
		} break;
	}
}

Later, we provide a boat:

void drive(int type, void* obj)
{
	switch (type)
	{
		case CAR:
		{
			Car* car = (Car*)obj;
			// ... Logic to accelerate car
		} break;
		case BUS:
		{
			Bus* bus = (Bus*)obj;
			// ... Logic to accelerate bus
		} break;
		case BOAT:
		{
			Boat* boat = (Boat*)obj;
			// ... Logic to accelerate boat
		} break;
		default:
		{
		} break;
	}
}

As you can probably see, it’s relatively easy to figure out where to insert the code, but the maintenance of this can increase quickly, if you take into account that each function, such as drive, park, accelerate, addFuel, etc… would each need this sort of switch statement. You would wind up changing a lot of working code.

Object-Oriented Programming

Object-Oriented programming could be considered the next phase in the evolution of programming languages.  It largely gained popularity due to C++ (formerly C with Classes).  Object-Oriented development changes the emphasis.  The emphasis in Object-Oriented programming is not with defining the functionality of the system and the data.  Instead of putting the emphasis on the data of the system, you start out by identifying the objects in the system.  So, imagine a game, such as the original Super Mario Bros.  You could identify objects such as your main character (Mario, Luigi), the enemies in the world (Goombas, Koopa Troopas, Bowser, etc…), the blocks, the pipes, moving platforms, and even the world itself.  The functionality is tied in when the objects communicate with each other. In technical terms, this communication is called messaging. The functions are owned by objects, and are called methods, instead of functions. This ownership is based on something being able to do something else.  For example, Mario can jump, so Mario might have a method called jump().  Mario can also shoot fireballs, so he would have a method called shoot().  Since Mario and Luigi are the same, they might simply be two separate object instances of the same class called Player.  The enemies have some similarities, so they could be structured with a base class called Enemy and derived classes, which implement the different functionality.  It’s a different way of thinking about things.

Now what I’ve described so far might not make sense if you’re not proficient with Object-Oriented programming, so let me go back to the Vehicle example.  Here’s what it would look like in OO-terms:

class Vehicle
{
public:
	virtual void drive() = 0;
};

class Car : public Vehicle
{
public:
	virtual void drive()
	{
		// ... Logic to accelerate car
	}
};

class Bus : public Vehicle
{
public:
	virtual void drive()
	{
		// ... Logic to accelerate bus
	}
};

class Boat : public Vehicle
{
public:
	virtual void drive()
	{
		// ... Logic to accelerate boat
	}
};

In it’s most simple form, OO is simply a reorganization of code. However, it is obviously much more than this and this is a very simple example, which doesn’t touch all of the depths of how far things can go, but I think is fine to start. When you say that a Car is derived from a Vehicle, you are effectively saying that a Car is-a Vehicle. This is the basis for this type of inheritance. You should only derive if you can logically say that something is something else. For example, you shouldn’t have Bus derive from Boat, because a bus is-not-a boat.

So, if you look at the above example, I think you can see how this flows really nicely for things like GUIs. That’s why you can have a framework where every visual element might be derived from Control, Widget, or even Window (Side note: except in Actionscript, where for legacy reasons, everything is nonsensically derived from MovieClip). There’s logic behind this. A button is-a control. A push button is-a type of button. A list box is-a type of widget or control. And so on… It gets a little trickier when the base class is called Window (or CWnd in MFC), but if using this type of framework, you can try to accept the notion that each control could be considered a window, even though there were better name choices.

Object-oriented suffers from a set of problems of its own, even though it is an improvement over procedural programming. The first is that there’s more typing, at least upfront. As developers, we try to reduce typing, but OO can often be more verbose than necessary. Of course, wizards and newer programming languages aim to reduce this overhead more than languages like C++ or Java, which can often be overly verbose. The OO theory, though, is that through reuse, you avoid much of this typing as you develop higher-level things because you’re basically picking from a toolbox. OO also suffers from not having the same traceability that you have in procedural programming, because functional requirements do not map directly into design anymore, nor into code, nor into testing. When doing Object-Oriented Design, Object-Oriented Programming and Object-Oriented Testing, the traceability becomes less direct, and so newer processes try to take this into account a bit more.

· · · · · · · · · · · · · · · · ·

Nov/09

16

Flash and FLA Structure

So, recently I have been working with Adobe Flash, working on my first multiplayer Flash game. I normally have been focusing on the server-side of these sorts of games, but this time I get to work on both sides of the puzzle, which I am very excited about. I can’t provide any particular details about the project, but it is an interesting project, nonetheless. With that said, I ran into some caveats with the design of Flash FLAs, that I would like to talk about.

Introduction to the Problem

The first thing to note is that I made a branch from a single player version of this game, which still also has some changes which occur from time to time. When I made my code changes, I hadn’t realized how the art was embedded in the FLAs. Artists sometimes have the habit of directly embedding images in the FLA and not providing the actual source image. Furthermore, all of the UI changes that you would normally find in some sort of an external resource file is embedded directly in the FLA structure. Finally, the FLA format is binary and not published.

Because of these facts that I mentioned, when I went to merge my FLA with the one from the trunk, they were conflicted, with no mechanism for resolution. I had a discussion with some people and everyone lamented that Adobe had intentionally decided not to open up the FLA format.

Alleviating the Problem

After some more discussions, it became clear that there are a few things to help out the problem. The first is better communication between programmers and artists about what is actually being changed. Oftentimes, people make changes and don’t really communicate with each other well enough, and so each cog knows their piece, but perhaps not what other people’s pieces are. This is just a general thing and not limited to Flash, but certainly is worsened by the unfortunate design of Flash FLAs.

Another idea has to do with Flash SWC modules. Flash SWC modules are analogous to your typical C++ style static library (e.g.: .lib on Windows compilers or .a on Unix). Flash SWC modules give you a means to distribute both your compiled code and your GUI code into different modules. This makes a lot of sense to me. It’s more work upfront, but by using the Flash SWC modules, you can distribute different UI screens and panels to having owners, which I think is much more reasonable and makes the merging much easier. Of course, it doesn’t fix the problem, but it certainly turns a disaster of a problem into a more managable one.

If you have any more tips about how to streamline this process or any information about whether this may become more maintainable in CS5, I think that would be very interesting. Please let me know your thoughts.

Sources:
http://www.communitymx.com/content/article.cfm?cid=dc2c0

· · · ·

Theme Design by devolux.nh2.me