Pages

Showing posts with label designing. Show all posts
Showing posts with label designing. Show all posts

Sunday, May 30, 2010

Property Driven Code

Sometimes I feel like this,



trapped in a hard to maintain spaghetti code. I find myself writing again and again fragile code.
My definition of fragile code is, suppose you want to add a feature - good code, there's one place where you add that feature and it fits; fragile code, you've go to touch ten places.
Ken Thomson,  Coders at Work
The program may be structured but that does not exclude spaghetti code. The two are not mutually exclusive. Embedding the application's behavior or logic or -even worse- data properties is a path that leads to spaghetti code; pull it here and something moves on the other side.

But, what do I mean by Property Driven Code and how it can help me to reduce spaghetti code?

In its core lays a Data Driven design along with Property Modeling.
Here is how that kind of model looks like:



The programmer's main job is to write Property Driven Code, that means code that introspects data properties, mostly at run-time, and do stuff accordingly. Introspection, or reflection, is the magic thing that can reduce code complexity and hard-coded outer world knowledge.Yes, properties drive the code.

Properties, or Prototype-based programming, is similar to OOP but not the same thing. You can read Steve Yegge's great article The Universal Design Pattern by which I got inspired and wrote my proto_t data structure so I can use property modeling in my C++ projects.

Now I'll try to illustrate the concept with a simple example. Suppose that we have to load and save tabular data from and into text files. The file formats are from 3rd party software and cannot be change. Some of them are similar to CSV format but they can have slight differences. Or they might not be CSV but just lines with fixed length fields. If you think that's an unlikely scenario then welcome to the world of Electronic Cash Registers. How would you approach that problem? Would you use well known and tested CSV parsers? Write your custom parser? And if you pick up a library to do the job how would you structure the different format cases? By using a switch case? OOP and polymorphic classes? Plain old if-else chains?

Let's suppose we have to parse a file that contains lines like this one:
"hello, world", 42

That's a quoted string followed by a comma delimiter and an integer. If we choose to use Properties to design a solution, we'll have to declare a format object with 2 field entries which could have the below properties:

   name = "Description"
   maxSize = 12
   quoted? = true
   text? = true
   delimiter = ","
   

   name = "Magic Number"
   maxSize = 4
   quoted? = false
   integer? = true
   delimiter = ""


The above properties describe the line format quite accurately, thus they are sufficient for driving code to parse or construct such lines. So, with that format we can construct an appropriate model to store the data, customize a table control to display the data, serialization and deserialization code and what else we might need. Also note that the two fields may or may not share the same properties. In the OOP world, such specialization is a bit of problem and either we'd had to spread the properties among specific classes or put all of them in a base class and just let subclasses to ignore some of them. In a prototypal inheritance, Property model that is, classes do not exist. The properties define the object class.

As an example, our deserialization routine can construct a regular expression from the above format, on the fly, to extract the fields from the line.
Eg, pattern = ^"([^"]{,12})",(\d{,4})$

That way we can create an infinite number of little parsers to extract data, even from cranky formats, simply by taking advantage of regular expressions driven by properties. Cool, isn't it? And the best part is that we don't have to hard code format-logic in our code.

OK, that's the basic idea. The main point is that if we declare data relationships and data properties we can exploit run-time introspection and that's a powerful design technique. Whatever we do we'll have to add  functionalities at some point in the one way or the other. If you don't automate, somehow, the data manipulation you'll have to explicitly do it. No way to avoid that.

Monday, May 17, 2010

PLAN, bindings by name?

PLAN is a small framework which I've developed in C++, so I can declare application's behavior in one place. At the time, it's immature. In the future I intend to add JavaScript support in my projects (Qt4 framework). That will allow me to get rid of C macros and do modifications and inspection at run-time.

It's quite obvious that I repeat object names in the below example. I'm thinking of implementing bindings by name in the future, thus duplicated and error-prone code will be removed.

PLAN(on-download-items, C_(*T*, markItemsModel) <<
                        C_(*T*, @on-download));
PLAN(on-download-bcItems, C_(*T*, markBcItemsModel) <<
                          C_(*T*, @on-download));
PLAN(on-download-clerks, C_(*T*, markClerksModel) <<
                         C_(*T*, @on-download));
PLAN(on-download-groups, C_(*T*, markGroupsModel) <<
                         C_(*T*, @on-download));
PLAN(on-download-departments, C_(*T*, markDepartmentsModel) <<
                              C_(*T*, @on-download)); 
//
PLAN(on-download, C_(~IsDlgMarked, *DROP*) <<
                  C_(*T*, disableDlg) <<
                  C_(*T*, downloadFile) <<
                  C_(*T*, enableDlg));
PLAN(on-file-downloaded, C_(*T*, @on-load-model));
PLAN(on-load-file, C_(*T*, OpenFileDialog) <<
                   C_(*T*, @on-load-model));
PLAN(on-load-model, C_(*T*, detachView) <<
                    C_(*T*, loadModel) <<
                    C_(*T*, attachView) <<
                    C_(*T*, customizeView));


By the way, if I tell you that I use dialogs and tables to display data, can you understand how my application behaves? Imagine that a button click can trigger a "on-download-items" event, for example.

Tuesday, May 4, 2010

Knuth, emphasis on function as well as form is basic to design problems

The Art of Computer Programming, Volume 1
2.2 LINEAR LISTS
2.2.1 Stacks, Queues, and Deques, pg. 238

[...]

We must decide in each case how much structure to represent in our tables, and how accessible to make each piece of information.  To make such decisions, we need to know what operations are to be performed on the data.  For each problem considered in this chapter, therefore, we consider not only the data structure but also the class of operations to be done on the data; the design of computer representations depends on the desired function of the data as well as on its intrinsic  properties.  Indeed, an emphasis on function as well as form is basic to design problems in general.

Thursday, April 29, 2010

Making and Breaking the Grid

Thoughts on Structure: An introduction
[...]
Like items are arranged in similar ways so that their similarities are made more apparent and, therefore, more recognizable. The grid renders the elements it controls into a neutral spatial field of regularity that permits accessibility - viewers know where to locate information they seek because the junctures of horizontal and vertical divisions act as signposts for locating that information. The systems helps  the viewer understand its use. In one sense, the grid is like a visual filing cabinet.


I read about the typographical grid (an organizing principle in graphic design) in the book About Face 3: The Essentials of Interaction Design, Part II: Designing Behavior and Form. Whoa! I was struck by a bolt of lightning. I learned something really useful and powerful at the same time. From that moment, I see graphic interfaces from a totally different perspective. Now I consider grid a must in my designs. Not only it arranges elements in more appealing, to human eye, positions but it also gives you a form to work with. To learn more about the grid and get a feeling of how professional designers make use of that technique, I bought a copy of the book, which I already mentioned,  Making and Breaking the Grid.

Well, I began to use that technique and manually arrange, and resetting, the GUI elements. By manually,  I mean that I had to write extra code. Unfortunately, the programming environment I used did not support grid-like behavior.

And then the Qt framework came.

A couple of weeks ago I decided to stop wasting time with inferior programming frameworks and switch to a better one. I choose Qt. Every time I explore Qt,
I have a that's great, that's cool, that's f*cking awesome, moment.
( I had a similar experience with the Lisp programming language.)

Yeap, Qt has layout managers; Qt classes that do all the dirty work for us.
You can either write code to handle the layout objects or use the Qt Designer,
which is of course much easier, especially for beginners.






Qt Designer in action. Watch and observe the grid structuring and the
auto arrangement of the objects, while we are resizing the form.




Bonus link: Let's Build a Grid