Showing posts with label Design Patterns. Show all posts
Showing posts with label Design Patterns. Show all posts

Two-Tier Or Three-Tier?


N by !Raimyu on deviantART

The N-Tier pattern, when used in software development, is one step above my usual topic of design patterns. They are commonly called architectural patterns which are concerned with the software at a macro level (eg. ‘the big picture’).

Some time ago, I was tasked before of maintaining a line-of-business sales system from a fairly large company.Their technical design spec was quite clear that the “…architecture is divided into three (3) main layers…” which, in theory, should make my job easier. As I browsed through the code though, one thing became apparent: It was not a 3-Tier Arch like the docs said, but a more traditional server-client setup~ Now, what is the difference exactly?

A Server-Client architecture (which is, technically, a 2-Tier Arch) is concerned primarily with the centralization of data and sometimes the balancing of process load to either the server or the client. The data and the business rules (stored procs) are stored at the server, with a thin client app to present the results (forms, grids & reports)- which is exactly how the LoB app above works.

S+C’s Advantages over 3-Tier Arch

  • Faster Development (less design, less code)
  • Can offload processes to the server to accommodate for weaker client workstations, or vice versa if the server is the performance bottleneck
  • Can change business logic without re-deploying new software to the user

Three-tier applications on the other hand, is focused on the separation of responsibility to facilitate control and change. The Data Access Layer is usually separated physically such as a Database Server, but is mostly kept “dumb” except for very few performance functions. The Business Logic Layer on the other hand is a more robust collection of libraries and maybe a few dynamic scripts that enforces the rules of the application. This ranges from who can access which data, data validation, up to caching, etc. Lastly, the topmost Presentation Layer is the combination of UI Rendering (Windows Forms, ASP.Net, WPF, etc.) and UI Logic (Parallel processes, Sessions, States, anything that is not business-related logic).

3-Tier’s Advantages over S+C Arch:

  • Modular, and thus easier to maintain. You can replace one layer with another completely with very minimal code changes (switch from Windows Forms to WPF or ASP.Net with zero impact on business logic or database schema)
  • can perform Unit Testing very easily. Since all of the business logic is contained on libraries, you can hook the DLLs easily on a controlled testing environment.

We have to consider both sets of factors above in order to decide which architecture to use when designing our software~

C#4.0 & The Decorator Pattern

The decorator pattern can be used to make it possible to extend (decorate) the functionality of a certain object at runtime, independently of other instances of the same class, provided some groundwork is done at design time. (http://en.wikipedia.org/wiki/decorator_pattern)

Design Pattern: Decorator Patten
Pattern Type: Structural
First Stated in: Code Complete, Steve McConnell (1st Edition)
Description: Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality.

One of the features of C# 4.0 is the dynamic keyword. Basically used like the var keyword, a dynamic object defers type-checking until runtime. A simple example:

static void Main(string[] args)
{
dynamic pet;

pet = new dog();
Console.WriteLine(pet.kick());

pet = new cat();
Console.WriteLine(pet.kick());

pet = new lion();
Console.WriteLine(pet.kick());

Console.ReadKey();
}

class dog { public string kick() { return "ROWRrr!"; } }
class cat { public string kick() { return "MEOWRrr!"; } }
class lion { public string kick() { return "OmNomNom-"; } }

Make no mistake, that is still fundamentally C#, with all the static type-checking done in the background (mostly in runtime). Anyway, we can also use the dynamic keyword to implement the decorator pattern- which extends a function of a class.

class Program
{
class Zergling { public float cost() { return 1; } }
class BanelingMorph
{
dynamic zergling { get; private set; }
BanelingMorph(dynamic z) { zergling = z; }
float cost() { return zergling.cost() + 0.5f; }
}
class AdrenalGlands
{
dynamic zergling { get; private set; }
AdrenalGlands(dynamic z) { zergling = z; }
float cost() { return zergling.cost() + 0.7f; }
}
class MetabolicBoost
{
dynamic zergling { get; private set; }
MetabolicBoost(dynamic z) { zergling = z; }
float cost() { return zergling.cost() + 0.2f; }
}

static void Main(string[] args)
{
dynamic DevoursChildren = new Zergling();
DevoursChildren = new BanelingMorph(DevoursChildren);
DevoursChildren = new AdrenalGlands(DevoursChildren);
DevoursChildren = new MetabolicBoost(DevoursChildren);

Console.WriteLine(DevoursChildren.cost());
Console.ReadKey();
}
}

I'm doing this while alt-tabbing between Starcraft2 Beta, so forgive the old zergling hero cameo ^^; Anyway, Decorators work a lot like Object "Upgrades", in a sense that they can change the resulting object by modifying functionality. I guess that's done~ Until the next design pattern, Sayonara XD

Specs (Both kinds)

Specifications (noun, plural)

1. A set of requirements defining an exact description of an object or a process.
2. In computer programming, a Design Pattern where business logic can be recombined by chaining the business logic together using Boolean logic.

Part of almost every development life cycle is the design stage. This is where you determine the requirements of the application, if its feasible, and if so: a) how to implement it and b) how to test if the implementation works. An analogy: If an application is a house, one of the first things to determine is the number of rooms & floors, which materials to use, etc. Specifications are the documents that is produced after the design stage, which is basically the blueprint of the house.

Many programmers skip the design stage, opting to code directly. Big Mistake. That’s like building a house without any documents: no blueprint, no materials manifest, etc. Sure, it might work but only after a lot of trial and error (basically, the failed apps becomes your documents). And even if it does work, who in their right minds would live in that house? Without specs, its hard to test if works or not.

The specifications design patter, on the other hand, is quite different. Sometimes, business logic objects can be “chained” together like so:

ISpecification CardsToPrint = Red.And(Even.Not()).And(Facecard); 
ISpecification CardsToPrint = Even.And(Red.Not()).Or(Facecard); 
ISpecification CardsToPrint = Facecard.Or(Even.Not());
Design Pattern: Specification Patten
Pattern Type: Behavioral
First Stated in: http://www.martinfowler.com/apsupp/spec.pdf
Description: Recombinable business logic in a boolean fashion

My sample app uses a standard deck cards, then uses the Specification pattern to specify which cards to print. Of course, one can easily substitute “Employees” or “Places” with the collection of cards. Feel free to experiment with the CardsToPrint variable: to check the results quicker, comment out the shuffle method.

Source Files (in C# 4.0): SpecificationsPatternExample_Source.zip

Specifications: A couple of important computer science topics that has the same name but different meanings~

Singletons

I was experimenting with C# 4.0’s parallel functions (specifically parallel.foreach) and I had problems with a database-file sharing permission exception last night. What’s funny is, that’s supposed to be impossible. The Database Server object was a singleton, which meant that you cannot instantiate more than one instance of the class.
Design Pattern: Singleton
Pattern Type: Creational
First Stated in: http://en.wikipedia.org/wiki/Design_Patterns_(book)
Description: Ensure a class has only one instance, and provide a global point of access to it.

I started with this code:
public static DataManager Instance 
{
get; private set;
}
static DataManager()
{
Instance = new DataManager();
}
private DataManager() { }

Fairy standard. Line 1 exposed the instance, lines 5-8 is an internal lazy initialization, and the last line prevented the consumer from initializing the class themselves. Can you guess how the program managed to get around this limitation? It turns out that my application is a bit too fast. I mentioned earlier that I used Parallel.ForEach to access the object: this means that every cycle of the for loop is done in parallel of each other. If I had at least two objects inside the ForEach, and there’s enough CPU and RAM remaining, they would both run at the same time- initializing the object twice.

Poking around the web for solutions, I found one that used a double-locking algorithm which (guess what?) locked the instance from other parallel threads.
private static volatile DataManager _Instance;
private static object syncLock = new object();

public static DataManager Instance
{
get
{
if (_Instance == null)
{
lock (syncLock)
{
if (_Instance == null)
_Instance = new DataManager();
}
}
return _Instance;
}
}

private DataManager() { }

Line-by-line: The first line uses a keyword that I haven’t seen since college: volatile. The keyword locks the the _Instance field until it is initialized and fully accessible. Next line (2) is a dummy field of type: object which we see again on line 10- basically, we’re avoiding a deadlock by making the object always accessible, which is only possible if we don't lock the type itself (DataManager) down. The other lines are self-explanatory: A lazy initialization and a constructor that blocks the consumer from initializing more objects.

I compiled the app and it looks like everything works as expected for now :) Until the next bug, ciao~!

Lazy ain’t Always Bad…

You can fire up Microsoft Word, type something up quick, save (and/or publish) then close the app down, in a couple of minutes. Only the relatively quick splash screen would force you to wait as the program loads before you can start writing.

As a developer, you should (as a rule) make your software as quick as possible, and one of the more popular tactics to do this is by delaying to load an object until you actually need it. You can see this approach in Microsoft Word: Behind the splash screen, the app loads only the necessary UI (the document view, the ribbon, etc.) and after everything’s good, shows it the user. Since the user doesn’t always need, say, the font dialog box, then it isn’t initially loaded. A click in the right button however, would load the form on the fly and show it to the user. This concept is called Lazy Initialization.

Design Pattern: Lazy Initialization
Pattern Type: Creational
First Stated in: Patterns of Enterprise Application Architecture
Description: Lazy Initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed
    public class DataManager
{
private Server _ServerOne = null;
public Server ServerOne
{
get
{
if (_ServerOne == null)
this._ServerOne = new Server();
return this._ServerOne;
}
}
}

As you can see from the code above, first it checks if the object has already been initialized. If it is, then it hands over the already live object, but if not- then it initializes the object on the fly before handing it over. This means that the second time the object is needed, it would be quicker since you don’t have to initialize it again.

Now, before I hit publish on this post, I just want to say that the topic is not, in any way, connected to why there wasn’t a blog post yesterday =P I'll try to get two posts up today to make up for it~

Abstract Factories

I was designing an application’s Data Access Layer when I realized that the Objects that needed to be persisted can rapidly grow. This meant that I can’t use Binary or XML Serialization due to memory limits, but I can’t use a full relational database either since some of the objects needed to be stored in the memory for quick access. So my only options are memcached key-value database, a combination of relational (for long term data) and Binary/XML serialization (for short term data) or use Db4o plus a clever design pattern called “Abstract Factories”. Of course I went with the simplest path (for me, at least).

Problem: You need to persist (save to storage) a number of related objects.

Solution: You can use Abstract Factory pattern in conjunction with Db4o.

AbstractFactoryPatternExample

Design Pattern: Abstract Factory pattern
Pattern Type: Creational
First Stated in: http://en.wikipedia.org/wiki/Design_Patterns_(book)
Description: the abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme (eg. related to each other)

First, I encapsulated all of the Db4o stuff in the Abstract Classes. The abstract server factory act as the databases while the abstract client products are basically tables, or the enumerations of the abstract data. Now, why are all of them abstractions? So that when there’s a new database, you only need to inherit the ServerFactory and it automagically works~! Same goes for the other abstractions. In fact, you can add properties to the concrete data objects (eg. add quantity to OrangeData and/or price to GrapeData) and all of it would be persisted!

As you can see in the attached C# Console solution below, the actual business logic are totally oblivious to the Db40 stuff going on in the background, while all of the Server/Client/Data objects just inherited the Data Access Layer classes in the AbstractFactory+Db4o library. Tinker with the app, add properties to the Data, add more servers/clients and see how powerful this combination of technologies really are.AbstractFactoryPatternExample_Source2

Download Source Here: http://ow.ly/1zHeI
Download Release Here: http://ow.ly/1zHgv