Wednesday, July 27, 2011

Decoupling classes for user interfaces

Someone recently asked the following question on Stack Exchange:

What is the best practice when it comes to writing classes that might have to know about the user interface. Wouldn't a class knowing how to draw itself break some best practices since it depends on what the user interface is (console, GUI, etc)?

In many programming books I've come across the "Shape" example that shows inheritance. The base class shape has a draw() method that each shape such as a circle and square override. This allows for polymorphism. But isn't the draw() method very much dependent on what the user interface is? If we write this class for say, Win Forms, then we cannot re-use it for a console app or web app. Is this correct?

The reason for the question is that I find myself always getting stuck and hung up on how to generalize classes so they are most useful. This is actually working against me and I'm wondering if I'm "trying too hard".

My answer was as follows:

There are a number of tried and true design patterns that have been developed over the years to address exactly what you are talking about. Other answers to your question have referred to the Single Reponsibility Principle - which is absolutely valid - and what seems to be driving your question. That principle simply states that a class needs to do one thing WELL. In other words raising Cohesion and lowering Coupling which is what good object oriented design is all about - does a class do one thing well, and not have a lot of dependencies on others.

Well...you are right in observing that if you want to draw a circle on an iPhone, it will be different than drawing one on a PC running windows. You MUST have (in this case) a concrete class that draws one well on the iPhone, and another that draws one well on a PC. This is where the basic OO tenent of inheritance that all of those shapes examples breaks down. You simply cannot do it with inheritance alone.

That is where interfaces come in - as the Gang of Four book states (MUST READ) - Always favor implementation over inheritance. In other words, use interfaces to piece together an architecture that can perform various functions in many ways without relying on hard coded dependencies.

I've seen referece to the SOLID principles. Those are great. The 'S' is the single responsiblity principle. BUT, the 'D' stands for Dependency Inversion. The Inversion of Control pattern (Dependency Injection) can be used here. It is very powerful and can be used to answer the question of how to architect a system that can draw a circle for an iPhone as well as one for the PC.

It is possible to create an architecture that contains common business rules and data access, but have various implementations of user interfaces using these constructs. It really helps, however, to have actually been on a team that implemented it and see it in action to really understand it.

This is just a quick high-level answer to a question that deserves a more detailed answer. I encourage you to look further into these patterns. Some more concrete implementation of these patters can be found as well known names of MVC and MVVM.

Thursday, April 21, 2011

Unit Testing a Waste of Time?

A Linked-In user recently posted the following question:

How much time do you spend debugging? How much time do you spend dealing with software bugs? Is debugging something that bothers you and wastes your time, or not much of a concern?

Well, I have to admit I'm VERY anal when it comes to unit testing code, and am just as vehement (OK...sometimes a jerk) when it comes to my teams regarding unit testing before it gets sent out. I have known some developers who make a quick change and then check their code in before even running it through a "smoke test". They feel like the change is too minimal, or it is so minor that "nothing can break from this"...well...we all know what ASSUME means (ASS-U-ME).

I am NOT a TDD biggot. But, I truly think that the time spent up front to go through as many possible scenarios as possible (and more) will pay big dividends in the long run. Yes, I admit that I don't code as quickly as some because of that, but for the most part, I'm not going back a month later fixing some stupid bug that reared its ugly head because I was careless.

Regarding the question - "does it bother me or waste my time?" - absolutely not...that is part of the job, and if a developer doesn't like that part, then they may need to re-evaluate their line of work. Debugging is part of coding - part of the solution finding. And ultimately, when we DO find the solution - one of the sources of satisfaction behind our craft.

Thursday, December 9, 2010

ORM or SQL for real world project

Just answered a question on Linked-In regarding ORM vs. SQL for real world projects...here is my answer:


OK...Since I'm a consultant, I'll give you the consultant answer - "It depends".

Using an ORM such as Entity Framework makes it VERY easy to run CRUD routines against a database without having to do ANY stored procedures (or any other SQL for that matter). What you lose when you do that is the ability to fine tune the queries or have a lot of control of what the ORM will generate. Oh, yea...I know some will argue that you have a lot more control, but bottom line the tool is still generating SQL for you to perform that operation. A lot of DBAs don't like that because they too lose some control of what is actually happening on the database and the SQL being generated.

Managers love it because productivity is ramped up because we aren't generating a lot of SPROCs and other object code that takes time and has to be maintained.

You hit it on the money that if you want to go with the SQL approach, you will gain some performance because you lose a layer in the ORM, and have the ability to fine tune your queries - as well as them living on the DB server. BUT...you lose some productivity because now you need to generate those CRUD procedures as well as create the business layer around them. Using a tool like MyGeneration can mitigate that some, but you still have code to maintain.

Bottom line, if HIGH performance is an issue, then I would stick to the old fashion, tried-and-true SPROCs and associated objects layers. However, for most real-world line-of-business applications where you have a few dozen or a few hundred users and a "normal" level of performance is expected, then I would take advantage of the productivity enhancements gained by the ORMs.

Monday, July 27, 2009

Best Practices and your "Personal Brand"

OK...I cannot take credit for this. It comes from Scott Hanselman's blog. I really liked it and wanted to post it here for easy linking/viewing.

Hanselman's original post is here.

Consciously manage your personal brand.
You work here to help the company, but also yourself. No one will manage your “personal brand” except you. How are you perceived? Do you know? Take negative feedback gracefully, and implement change. Rinse, repeat.

Push the Limits
Chris Sells told me once, If you’re not getting in trouble with your boss at least twice a year, you’re likely not pushing the envelope hard enough. Two slaps a year might be the cost for 10 successes. If you’re not moving forward, well, you’re not moving forward.

Conserve your keystrokes.
When you’re emailing a single person or a reasonably sized cc: list, ask yourself, are you wasting your time? Is this a message that 10 people need to see, or 10,000? Is email where you should be spending your time. Actively be aware of the number of people you communicate with , and the relative level of influence. Is a blog post seen by 50,000 more or less valuable than a single email to your skip-level? Only you can answer, but only if you’re consciously trying to conserve your keystrokes. Your fingers DO have an expiration date; there’s a finite number of keystrokes left, use them wisely.

Don’t give bile a permalink.
While you’re on the clock, think about what you tweet and FB. It only takes one bad link to undo a year’s work. Same goes for tweeting product launches before they’ve launched.
Write down what you’re trying to accomplish and hang it on the wall.
Make T-Shirts. Tell your spouse and kids. If you’re working towards a goal, tell people. It’ll keep you honest and it’ll motivate you. Saying things out loud help make them reality.

Manage Up
Are your commitments aligned with your boss and your bosses boss? Do you have visibility into their commitments? If not, ask for them. Make sure your accomplishments are making yourself, and your boss, look good.

Have a System to Manage Information Flow
If you’ve got 1000 emails in your Inbox, it’s not an Inbox. It’s a pile of crap. Have a system, any system, to triage your work. Any item in your inbox should be processed: Do it, drop it, defer it, delegate it. There are no other actions to take. Are you effectively managing your information flow? Try scheduling time for email on your calendar.

Monday, July 20, 2009

Dudley's Bad Advice

Just responded to an article on examiner.com. Wow...what kind of advice/attitudes are out there these days!! See below...

Article:

http://www.examiner.com/x-3040-Life-in-the-Cubicle-Examiner~y2009m7d12-Dear-Dudley-Should-I-quit-my-day-job-after-starting-my-own-business

My response:

Dudley -
I cannot believe the AWFUL advice you actually put in print and published for all the world to see. "Stop caring" and "Try to get laid off"...what is that?!?!?

Where is your personal pride in a job well done? The real character of a person is measured not in what someone does when people are watching, but what a person does when no one is around. You say to "always be incredibly couteous" but you can see this kind of passive aggressive attitude a mile away. This kind of behavior only burns bridges with not only your current company, but the co-workers that are relying on you to do THEIR jobs...which some of them DO enjoy and have pride in.

Remember...we are not only accountable for ourselves! Do a GOOD job and have pride in your work - ALL THE TIME - whether or not it is for someone else or for you. Your name and your reputation are ALWAYS going to follow it.

Wednesday, July 1, 2009

LINQ-SQL – Incorrect results from Count() from Lambda expressions

Joel Varty recently had a question on his blog:

http://weblogs.asp.net/joelvarty/archive/2009/03/06/linq-sql-incorrect-results-from-count-from-lambda-expressions.aspx

My answer to this issue is below...

I’m surprised Joel didn’t answer his own question of “Can anyone explain this?”…HE is the expert…anyway…I’ll venture my own 2 cents (may be all it’s worth):

The answer is because the Select operator is used to create an output sequence of one kind of element to another type of element. In other words…you have a list of “stuff” and you want to extract another list using the first list as the base. The lambda expression used does not FILTER; rather, it MASSAGES the output data to look the way you want it.

Just as illustration:

You can do the EXACT same thing on the AdventureWorks database. The following uses a quick 5 minute mock up using AdventureWorks and the Entity Framework to access the data:


//ObjectQuery employeeQuery
AdventureWorksEntities entities = new AdventureWorksEntities();

ObjectQuery employees = entities.Employee;

int count1 = employees.Count(p => p.Gender == "M");
int count2 = employees.Select(p => p.Gender == "M").Count();
int count3 = employees.Count(p => p.Gender == "F");
int count4 = employees.Where(p => p.Gender == "M").Count();

System.Diagnostics.Debug.WriteLine(string.Format("Males (way 1)(Correct - uses Count): {0}", count1));
System.Diagnostics.Debug.WriteLine(string.Format("Males (way 2)(Incorrect - Uses Select): {0}", count2));
System.Diagnostics.Debug.WriteLine(string.Format("Females (way 1)(Correct - uses Count): {0}", count3));
System.Diagnostics.Debug.WriteLine(string.Format("Males (way 3)(Correct - uses Where): {0}", count4));

Your results will be:

Males (way 1)(Correct - uses Count): 206
Males (way 2)(Incorrect - Uses Select): 290
Females (way 1)(Correct - uses Count): 84
Males (way 3)(Correct - uses Where): 206

The WHERE statement does the similar thing the count does, so you will get the same results.

The proper use of Select would be to get a different view set of employee Data….kind of like the following using anonymous types:

var employeeStuff = employees.Select(p => new
{
AmAWoman = p.Gender == "F",
SSN = p.NationalIDNumber,
UID = p.LoginID,
Title = p.Title,
DOB = p.BirthDate,
Motto = p.Gender == "M" ? "I am a Man!!" : "A am Woman - watch me Roar!"
});

foreach (var item in employeeStuff)
{
System.Diagnostics.Debug.WriteLine(string.Format("{0}; {1}; {2}; {3}; {4}; {5}", item.SSN, item.UID, item.Title,
item.DOB, item.Motto, item.AmAWoman));
}


(results – only the first few)
14417807; adventure-works\guy1; Production Technician - WC60; 5/15/1972 12:00:00 AM; I am a Man!!; False
253022876; adventure-works\kevin0; Marketing Assistant; 6/3/1977 12:00:00 AM; I am a Man!!; False
509647174; adventure-works\roberto0; Engineering Manager; 12/13/1964 12:00:00 AM; I am a Man!!; False
112457891; adventure-works\rob0; Senior Tool Designer; 1/23/1965 12:00:00 AM; I am a Man!!; False
480168528; adventure-works\thierry0; Tool Designer; 8/29/1949 12:00:00 AM; I am a Man!!; False
24756624; adventure-works\david0; Marketing Manager; 4/19/1965 12:00:00 AM; I am a Man!!; False
309738752; adventure-works\jolynn0; Production Supervisor - WC60; 2/16/1946 12:00:00 AM; A am Woman - watch me Roar!; True
690627818; adventure-works\ruth0; Production Technician - WC10; 7/6/1946 12:00:00 AM; A am Woman - watch me Roar!; True
695256908; adventure-works\gail0; Design Engineer; 10/29/1942 12:00:00 AM; A am Woman - watch me Roar!; True
912265825; adventure-works\barry0; Production Technician - WC10; 4/27/1946 12:00:00 AM; I am a Man!!; False
998320692; adventure-works\jossef0; Design Engineer; 4/11/1949 12:00:00 AM; I am a Man!!; False
245797967; adventure-works\terri0; Vice President of Engineering; 9/1/1961 12:00:00 AM; A am Woman - watch me Roar!; True
844973625; adventure-works\sidney0; Production Technician - WC10; 10/1/1946 12:00:00 AM; I am a Man!!; False
233069302; adventure-works\taylor0; Production Supervisor - WC50; 5/3/1946 12:00:00 AM; I am a Man!!; False

Wednesday, June 24, 2009

HierarchyId in SQL Server

I just had a collegue send an email out to the team regarding the new HierarchyId in SQL server. I wanted to share with you my response to that. I'll start with His email and then follow up with my response.

Original Email:

I’m a bit worried by posts like this:

http://www.sqlskills.com/blogs/simon/post/SQL-Server-2008-HierarchyId-whats-the-point.aspx

Does anyone know of a strong argument for using HierarchyId?

My Response:

Microsoft’s documentation on HierarchyId is found here:

http://msdn.microsoft.com/en-us/library/bb677290.aspx

I think conceptually, someone at Micro$oft decided that they wanted a new (data-centric) way of managing information in a hierarchy tree. It sounds like they wanted a one-stop-shop way of being able to parse and determine children and manage nodes that were aware of the current data structure. Just from the last few minutes of research, I cannot say that I’m sold on it seeing as I come from an “old school” of managing these types of relationships – good old fashion data structures and a good data model that logically describes what you are trying to convey. Adding an additional ID (and management layer) which lays the management responsibility on the database, in my opinion, reduces your flexibility and ability to manage the data as you need. What’s the old saying: some are willing to give up freedom for security/convenience – sounds like other things happening on a national level – ah, but I digress! (Enough on that)