In extremely formal programming environments, early design is done with UML diagrams. The intent is to discuss processes and steps independent of any programming language or final structure. There comes a time, though, that a programming style begins to become evident in the models. Usually this happens at around the design of the sequence diagrams.
In the sequence diagrams, the designer is indicating the objects and the calls that need to be made between objects. Again, this is supposed to be at a higher level than code, but many times it is taken pretty literally.
I'm as guilty as the worst. I try to make the sequence diagram show everything I want done to accomplish a task. It's like writing a code outline. In fact, I write pseudocode before I write the sequence diagram.
Why would I want to write the code before explaining to others how to write the code via diagram? The answer is Microsoft. Well, Microsoft is the inspiration. There isn't much doubt that when Microsoft gives you an API, it typically does a lot for you. One popular example would be the Application Blocks. The data application block compresses many lines of data access code into a single statement. Once you use it, you wonder how you got by without it.
So that's what I strive for in the design of objects. I want them to be simple and clear. I want them to do as much work as possible for the next programmer that comes along. None of this is new. But when you're coding an app, do you ever think about what another programmer would think of your objects? Would they be intuitive enough to use without generating a runtime error?
Sometimes, designing this way breaks the proper design cycle.
For example, you have a use case stating "User looks up customer record and sets user to Inactive." As the programmer, what kind of code would you like to write? I can think of a few different ways:
Dim c As Objects.Customer
c = Objects.Customer.Search("John", "Smith")
If c IsNot Nothing Then
c.Active = False
c.save()
End If
Or maybe:
Dim search As New CustomerLookup
Dim results() As Customers
results = search.FindByCustomerNumber(custNum)
Select Case results.length
Case 0
Throw New Exception("Customer not found.")
Case 1
results(0).InactivateCustomer()
Case Else
Throw New Exception("Multiple customer found for customer number.")
End Select
But the point is, you are trying to make the code as easy for the developer as possible. Because change is here to stay. What if you didn't think ahead with something like this? What possible nightmare code could you end up with?
Dim searcher As New Search
Dim results As SearchResults
searcher.Database = My.Settings.dbConnectionString
searcher.Table = "dbo.Customer"
searcher.SearchField = "CustomerNumber"
searcher.ReturnObject = GetType(Customer)
searcher.MatchType = MatchTypes.Exact
results = searcher.DoSearch
If results.ItemCount = 1 Then
Dim c As Customer = CType(results.ReturnObject(0), Customer)
c.Active = False
c.Save(My.Settings.dbConnectionString)
End If
And maybe the flexibility of the "Search" object is great, but there's no way a new programmer could figure out the initialization steps to create a search. Could this have been solved using code design? Maybe. Actually, that example was written spur of the moment and I'm not entirely sure it accurately illustartes my point. You'd have to assume that the Search object used to do one thing and it got enhanced over and over to do everything. That's for another story: objects should know only what they need to.
Here's a different example. Which code seems more logical?
Dim c As New Customer
c.load(customerNumber:=10)
For Each o As Order In c.Orders
Debug.WriteLine(o.GrandTotal)
Next
or
Dim c As New Customer
Dim co As Orders
c.load(customerNumber:=10)
co = New Orders(c)
For Each o In co
Debug.WriteLine(o.GrandTotal)
Next
In the first example, Orders is a property on the Customer object, where in the second example, Orders is a standalone object that has to be instantiated with a Customer object.
One of the drawbacks I would visualize is a new developer going straight to the Orders object even though they can't create it directly. The example isn't doing the problem justice. I'm thinking of a deeper object tree where it's not so straightforward to get to an object.
But anyway, I started by talking about design and ended up with a lot of code examples. So let's quickly try to wrap it up and ask: does a UML diagram illustrate these finer points? Can you end up with objects that will get coded like this if you purposely do not think of code while designing? Will your objects be self-aware or will they just be data containers with a bunch of methods to manipulate the data?
The answers lie with the developer.