December 22, 2008

Back to basics: Access Modifiers

Someone asked me this weekend about modifiers, what they are, how they're used and most specifically, what the differences are. They'd already done a search on Google and the explanations were hard to understand. Given the spirit of my blog and explaining programming terms in simplistic non-jargonated [if that's even a word?] language, I thought I'd post a quick note...

First up, what are the modifiers? Put in simple terms, modifiers are the keywords designated to mark code on a "Need to know" basis. For those of you that read/watch James Bond, you'll be familiar with this concept. For the moment, I will only cover the four most basic modifiers - Private, Public, Friend and Public, there are some others but they will just complicate the explanation unecessarily for the moment.

How does this apply to code design? Well - consider this, you want to write an API for later use by other programs/programmers, but you want to restrict access to different areas of your code to prevent it being tampered with unecessarily. So...let's apply my James Bond analogy to a simple programming model to explain this concept.

Create a new project called MI6 - this project is our assembly. It will be used to contain a political hierarchy restricting access to data and actions to interested parties on a need to know basis.

M controls MI6 and so she (or he if classic Bond is more your thing) has access to all information. Some of this information is for M's eyes only [private], only she has access to that. So lets consider M as the base class in our assembly and that all information marked as eyes only is read and committed to memory before it's shredded.

Enter stage left, Moneypenny, the cute red-head that's had a thing for James from the outset. As M's assistant, she could be considered an extension of M and thus has information to all information not specifically marked as for M's eyes only [private]. That is, anything marked as public, protected or friend.

And where would any of the 00 agents be without the gadgets they need to perform their job. We need our illustrious Q. Q is part of MI6's inner circle, but really doesn't have much control of anything. He needs to know everything the agents will be doing in order to design the most useful gadgets. He doesn't, however, need access to all of the information at M or Moneypenny's disposal. So let's add a Q class to our assembly too:

Namespace MI6

  Public Class M
    
    Private Property1 As String
    Protected Property2 As String
    Friend Property3 As String
    Public Property4 As String

    Private Sub DrinkWhisky()
      'Do stuff the rest of the agency 
      'don't need to know about
    End Sub

    Public Sub ControlTheAgency()
      'Do stuff to control the agency
    End Sub

  End Class

  Public Class MoneyPenny
    Inherits M

    'As you create methods/properties inside 
    'this class, you will see that you can 
    'only directly access the properties 
    'within our class M that are not marked 
    'as private - that is Access2, 3 and 4, 
    'but not 1

    Private Sub DayDreamAboutJames()
      'Waste time while supposedly working
    End Sub

    Public Function ArrangeCoverStory(ByVal Mission As String) As CoverStory
      'Arrange cover story for specified agent
    End Sub

  End Class

  Public Class Q

    'You will notice that from inside this 
    'class you can only access M's properties 
    'marked as friend or public - that is 
    'Property3 and 4, but but not 1 or 2.

    Public Function IssueGadget() As Gadget
      'Issue a gadget
    End Function

  End Class

End Namespace

So now we have our compiled our assembly we have a basic code representation of MI6's hierarchical structure - and no I haven't forgotten the 00 agents...

Because 00 agents are out in the world and could be compromised (captured & interrogated), we don't want them to have access to all of the information that the inner circle have access to, that could be disasterous for national security, so we will break these guys out into their own assembly. So create a new project for our agents, this way we can control their access to only the information that they really need access to.

Namespace Agents

  Public Class Bond

    'From inside this class you can only directly access
    'M's properties marked as public - that is Property 4, but
    'not 1, 2 or 3.

    Public Event GotTheGirl()
    Public Event FlirtedWithMoneypenny()
    Public Event KilledTheBadGuy()
    Public Event UsedGadget()
    Public Event CompletedTheMission()

    Public Sub GetTheGirl()

    End Sub

    Public Sub FlirtWithMoneypenny()

    End Sub

    Public Sub BlowThingsUp()

    End Sub

    Public Sub KillTheBadGuy()

    End Sub

    Public Sub UseGadget()

    End Sub

    Public Sub DestroyTheCar()

    End Sub

  End Class

End Namespace

As you will notice, James has a bunch of methods and events pertinent to him doing his every day job. When I reference M [by creating a new instance of my M class], I only have access to M's public properties and methods, what goes on behind closed doors remains behind closed doors.

There is one slightly more contrived example, and that is of the Protected Friend. The protected friend a combination of the protected and friend modifiers as you might expect. A property that is marked as protected friend can be accessed inside any class derived from this class or any other class within our assembly.

So that's what modifiers are for and how they can be used to protect the flow of your code.

December 18, 2008

Basic Concepts: SyncLock, Threading and Race Conditions

I thought I'd continue in the same vein as my previous post and explain another programming paradigm that while relatively simple to use once you understand it, is difficult to explain clearly to beginners and consequently very difficult to grasp - SyncLock and synchronizing access of multiple threads to common system resources such as files, objects and variables

Consider this scenario: a kindergarten teacher whose infants are all clamouring for attention. If the children are all speaking at once, nobody can be heard - the teacher's attention can't be in all places at once. Finally the teacher decides she must establish some ground rules and brings in a wooden spoon from home. Having announced to her class that nobody can have her attention unless they have the spoon, order is restored. If the spoon is on the table the first child to grab the spoon can have her attention and once that child has finished what they're saying, they must replace the spoon on the desk, at which point another child [notice I didn't say "next child", I'll come back to that] can grab the spoon and have their turn.

In programming terms, think of the kindergarten teacher as some resource that multiple threads may need access to, maybe an instance of a class, a file, a variable, whatever - it doesn't matter what the resource is except that we need to know that multiple threads (the infants in the kindergarten class) want access to that resource (the teacher) and must be controlled in some manner.

Enter stage left - the spoon, a.k.a. the SyncLock which serves the same purpose in that none of the threads can access the resource unless they have the spoon! What the SyncLock actually does is to essentially say (in my best southern accent) "I got the spoon and the rest o' y'all are gonna hafta wait 'til I'm dun!".

Now, in the meantime, every other thread also attempts to lock the resource by attempting the grab the spoon. But the spoon's gone, someone else already has it. Until the spoon is returned, they all sit and patiently wait like an Eskimo over a hole in the ice. The original thread puts the spoon back where it got it from and the quickest thread to grab it gets to access the resource and do what they have to do with it, and so the cycle continues.

Coming back to the point I made earlier where I said "another child" rather than "next child": This is a common error that new programmers make when they first start attempting to access objects with multiple threads - you cannot guarantee the order in which the threads are able to apply the SyncLock so you must make sure that your code takes this into account.

So what is a race condition?

Imagine one sheet of paper that each of the children can paint on, but only if the paper hasn't already been painted on by someone else. Each child looks at the piece of paper and says - okay, nobody's painted on it yet so now I can paint and they all do...the last child to finish painting sees what they painted over top of everyone else's picture and all the other children are upset because their painting is ruined. When each child made their evaluation about whether they could paint, nobody had and so they could all paint. In the programming world, this scenario is called a race condition... one way we can solve this is to use the spoon (SyncLock).

Let's alter the scenario slightly, you can only check to see if the paper is painted and paint on it if you have the spoon, otherwise you must get another piece of paper and paint on that.

The first child grabs the spoon. They then evaluate that the paper is empty and determine that they can paint on it and do.

In the meantime, the other children (other threads) attempt to grab the spoon, but can't because the first child has it. They all sit patiently and wait for the spoon [like our Eskimo]...eventually the first child finishes painting and returns the spoon. The quickest child to grab the spoon does and realises the paper is already painted. They grab a new piece of paper and start painting. So the cycle continues. Once all the children have finished painting we have a big stack of paintings and everyone's happy because nobody ruined anyone else's picture.

So this explains the concept of synchronizing resource access using SyncLock to prevent race conditions.

Basic Concepts: Pointers, Delegates, ByRef, ByVal and Asynchronous Programming

It came to my attention this week that asynchronous programming and delegates aren't that easy for people to understand and even if you do understand them, they're difficult to explain - okay, it came to my attention a while ago but it only occured me to write anything about it today. It's a concept, much like pointers that can take some getting your head around. There are many excellent in depth explanations of how to implement them found all over the internet but none of them seem to do a very good job of explaining the basic underlying concept in plain understandable English.

A friend of mine explained it to me a while back after I'd read 20 websites and numerous book excerpts trying to understand delegates and how they worked and what they were used for. The explanation is no more than a dozen lines of plain English that even a non programmer can understand. The legendary Jon Skeet asked me for this explanation yesterday and prompted me to wonder if so many well renowned authors find this concept difficult to explain, then maybe I should post it on my blog.

"Consider a very simple example of a manager and their assistant. The manager is very busy and asks the assistant to run off and do some tasks and tells her that upon completion of those tasks she must go to her pigeon hole where she will find further instructions awaiting.

In programming terms this is somewhat analogous to the concept of asynchronous programming. The assistant runs off and does what is asked of them and the manager goes about their merry way doing other more important manager tasks. The assistant returns upon completion of her task list and goes to her pigeon hole to find out what she needs to do next.

So in the programming world, let’s consider the manager the main processing thread of your application and the assistant as an asynchronous process. The delegate is the pigeon hole – the location to find the address of the method to run next. The instruction found in the pigeonhole is the callback method."

It occurs to me that pointers in general could be explained in much the same way. If I put a letter in your pigeon hole, you know where to find it. The pigeon hole is the pointer to the letter which is the variable and the value which is the contents of the letter. Then you get to pointers to pointers and pointers to pointers to pointers etc which I couldn't even grasp when I was beginning to learn programming no matter who tried to explain it to me. It basically becomes a treasure hunt of pigeon holes with police tape over them and a note saying "look in pigeon hole n" (where n is the number of a different pigeon hole)...finally in the last pigeon hole is the letter which is your variable, and the letter contents which is the value.

Lets forget pointers for a minute and use a similar example in a different fashion to explain the difference between passing values by reference or by value.

"The manager wants to give her assistant a message. She writes a message and takes a photocopy, giving the copy to her assistant. The assistant can now do whatever she likes with her copy, she can scribble all over it, she can tear it up and throw it in the garbage if she likes. The manager still has the original and it's untouched.

This is the same as passing a variable to a method by value. Consider in this example that the assistant's actions are the method and the photocopied note is the method's arguments.

For passing a value by reference consider this: Instead of giving the assistant a photocopy of the note, the manager writes her note on the whiteboard, the assistant makes her modifications on the whiteboard. The whiteboard itself in this scenario is the variable and what is written on the whiteboard becomes the variable which the assistant modifies by reference."

This effectively is the same as passing a pointer to the variable to the method which is in fact what passing a variable by reference means.

And so concludes a plain English example of the basic concepts of asynchronous programming, delegates, variables, pointers, by reference and by value...

I know I've simplified and skated over some of the nuances and implications of these concepts, but I hope that is of help to those that don't get it, and of help to those that find it hard to explain these concepts to others.