Monday, May 17, 2010

Model View Controller

The model view controller is a compound pattern. Its three parts are described as:

Model: This is the business logic of the application - things like its data, its underlying rules, things like that.

View: A view is a representation of the data to the user. For example, it could be a graphical widget that shows the current data, and updates itself when the data changes.

Controller: Controller deals with user input and handles the complexity of decision making on how to transform user actions into operations on the model.

So, what design patterns are we talking about?

- First off, the interface between the model and its clients (both view and controller) follows the Observer pattern. Both views and controllers register as observers on the model. This way when data changes, the view can update itself automatically. Also, the controller can transform the view based on certain things in the model changing.

- Second design pattern is Strategy. The controller is a strategy, that the view is composed with. A view can be composed with a different controller to get different behavior.

- Third design pattern is Composite, used by the view in its internal implementation. Typically view is a tree of menus, controls, etc. By telling the top level control to draw itself, the view can make the entire UI draw itself (for example) by using the Composite pattern.

Sunday, May 16, 2010

More design patterns

Factory method:
"The Factory method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclasses."

Abstract factory:
"The abstract factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes"

Singleton:
"The singleton pattern ensures that a class has only one instance, and provides a global point of access to it."

Command:
"The Command pattern encapsulates a request as an object, thereby letting you parameterise other objects with different requests, queue or log requests, and support undoable operations."

Adapter:
"The adapter pattern converts the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces."

Facade:
"The Facade pattern provides a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use."

Template method:
"The Template method pattern defines the skeleton of an algorithm in a method, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure."

Iterator:
"The Iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation."

Composite:
"The Composite pattern allows you to compose objects into tree structures to present part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly."

State:
"The State pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class."

Proxy:
"The Proxy pattern provides a surrogate or placeholder for another object to control access to it."

Tuesday, May 4, 2010

Sorting a file in C++

I always get amazed when I see the conciseness of this code (from The C++ programming language, by Bjarne Stroustrup). Its C++, not supposed to be as concise as a non statically-typed, typically interpreted, language.

This code will read in the names of two files, open the first file, read all the words in it, sort them alphabetically, remove duplicates, and write it to the second file.



int main()
{
string from, to;
// Read input filenames
cin >> from >> to;

// Open the input file as an ifstream
ifstream is(from.c_str());
// Get a string iterator over input file
istream_iterator ii(is);
// The default istream_iterator indicates EOF
istream_iterator eos;

// Read each word of the file into the vector
vector b(ii, eos);

// Sort all the words
sort(b.begin(), b.end());

// Open output file
ofstream os(to.c_str());

// Create an output iterator for the file, which will write a "\n" each time along
// with the string
ostream_iterator oo(os, "\n");

// Copy the vector into the file, skip dups
unique_copy(b.begin(), b.end(), oo);

// Error code - return 0 for successful completion
return( !is.eof() || !os);
}


This is truly a brilliant demonstration of abstraction. By creating iterators to deal with the input and output files, we can use the C++ standard library algorithms to do a variety of useful things. Truly beautiful.