Friday, September 14, 2007

Conversation about Patterns, Developers, and whatnot

(9:10 PM) Robert:

how's the job going this week?

(9:11 PM) Daniel:

better actually, we're digging into this arcade game
and I'm starting to understand things more

(9:11 PM) Daniel:

but its all-consuming in my head, i can't seem to think about anything else
i.e. dave's game

(9:12 PM) Robert:

that's understandable

(9:12 PM) Daniel:

I really want to help dave though, cause I want him to finish it

(9:13 PM) Daniel:

maybe on the weekends I'll have time

(9:24 PM) Robert:

i hate words that have extraneous letters
such as Lincoln

(9:24 PM) Robert:

what's that second L doing in there?

(9:24 PM) Daniel:

just hangin out man

(9:24 PM) Robert:

nobody says "Leen-koln"

(9:25 PM) Robert:

back to programming a bit...

(9:25 PM) Daniel:

I feel your pain

(9:25 PM) Robert:

have you read about "design patterns"?

(9:26 PM) Robert:

(along with "anti-patterns")

(9:26 PM) Daniel:

I'm staring at a book called Design Patterns at this very moment

(9:26 PM) Daniel:

not reading it, its on the table

(9:26 PM) Robert:

"Elements of Reusable Object-Oriented Software"?

(9:26 PM) Daniel:

you're meaning things like the factory method, singletons...etc

(9:27 PM) Robert:

yeah

(9:27 PM) Daniel:

yeah, that's the one

(9:27 PM) Robert:

cool

(9:27 PM) Daniel:

dedrick had it in the office and I'm borrowing it

(9:27 PM) Robert:

you're already light-years ahead of most developers

(9:27 PM) Robert:

of your own accord or upon his suggestion?

(9:28 PM) Daniel:

no, I've been wanting to learn about them

(9:28 PM) Daniel:

and it turns out he had just the book I was going to buy

(9:28 PM) Robert:

i was teaching Greg at work about the Strategy pattern today

(9:29 PM) Daniel:

I guess I don't know greg

(9:29 PM) Robert:

you don't

(9:29 PM) Daniel:

but yeah, I've been wanting to read up on the patterns for awhile now
after learning they existed

(9:29 PM) Robert:

do you know if that book also talks about "anti-patterns"?

(9:29 PM) Daniel:

not sure

(9:30 PM) Daniel:

not in the index
anyway

(9:32 PM) Daniel:

I don't understand something

(9:33 PM) Daniel:

you mention a lot that most developers don't do this, or know about that
but jeez, what do they know?

(9:33 PM) Robert:

they know how to write "spaghetti code" until it just barely works

(9:34 PM) Robert:

"spaghetti code" is probably what your early expirements looked like

(9:34 PM) Daniel:

that sucks, they don't even want to make it good?

(9:34 PM) Robert:

nope
they are victims of "good enough"

(9:37 PM) Robert:

http://www.amazon.com/AntiPatterns-Refactoring-Software-Architectures-Projects/dp/0471197130/ref=pd_bbs_1/104-0707808-5144724?ie=UTF8&s=books&qid=1189647010&sr=1-1

(9:37 PM) Daniel:

I guess I don't have enough time working with dedrick and the other guy to see what they're attitude is, they seem to be okay

(9:38 PM) Daniel:

sounds like a funny book
interesting

(9:39 PM) Robert:

this is the exact reason why i think i told you before - i'd rather hire a mediocre-but-passionate dev than a well-trained-but-unmotivated dev

(9:39 PM) Daniel:

I can see that

(9:40 PM) Daniel:

do you ever get input on who your company hires?
give input

(9:41 PM) Robert:

passion begets constant improvement and excellent developers that can encourage other devs

(9:42 PM) Robert:

lack-luster begets wasted time/effort and code that is difficult to maintain
no

(9:43 PM) Robert:

though i was asked to write a small code-snippet that would be presented to interveiwees to see what they understand about it
i'll show you - you won't get it - it's probably too difficult

(9:43 PM) Daniel:

ok

(9:46 PM) Robert:

    static class Foo<T> where T : new()
    {
        private static T bar = new T();
        public static T Bar
        {
            get { return bar; }
        }
    }
that's the whole class, and it's quite useful

(9:47 PM) Daniel:

ok, let me look

(9:47 PM) Robert:

i had to replace real names with Foo and Bar or else you'd know right away

(9:48 PM) Daniel:

don't tell me

(9:49 PM) Robert:

the point of the code in the interview isn't to see if you get it right, it's to see how much of it you can explain

(9:50 PM) Daniel:

it looks like a generic class that just makes things
to me

(9:50 PM) Daniel:

some parts of the code confuse me however

(9:51 PM) Robert:

explain...

(9:51 PM) Daniel:

explain what I don't understand?

(9:51 PM) Robert:

yeah

(9:52 PM) Daniel:

in the class heading, you have "where T : new()
I don't get that

(9:53 PM) Daniel:

maybe I'm just reading it wrong

(9:54 PM) Robert:

that is a "generic type parameter constraint"

(9:55 PM) Robert:

it say's "you can use any T as long as it has a default public constructor"

(9:55 PM) Daniel:

I see

(9:55 PM) Daniel:

is this an object factory?

(9:56 PM) Robert:

if a type only had a private constructor or the only public constructor (abbrv. "ctor") requires any parameters

(9:56 PM) Robert:

that's close - it's a very special type of "factory"

(9:57 PM) Robert:

want me to explain?

(9:57 PM) Daniel:

yeah, don't think I can get any closer

(9:58 PM) Robert:

hint: it's not building very many objects - "new T()" is only called once

(9:59 PM) Daniel:

a singleton?

(9:59 PM) Robert:

yep
it externalizes the concept of "singleton" to a separate generic class

(9:59 PM) Robert:

you would use it like this:

(10:00 PM) Robert:

WizardGame game = Singleton<WizardGame>.Instance();

(10:00 PM) Robert:

the Singleton class (Foo) ensures that there is only one

(10:01 PM) Daniel:

how does it do that?
what prevents you

(10:08 PM) Robert:

brb; putting dishes away

(10:09 PM) Daniel:

ok

(10:36 PM) Robert:

hey
i'm back

(10:37 PM) Daniel:

ok

(10:37 PM) Robert:

every question you ask me tells me more about what you know and don't know about C#/.Net

(10:37 PM) Daniel:

:)

(10:37 PM) Robert:

...as an interviewer

(10:38 PM) Robert:

at first, i knew that you at least understood the C# language at a basic level
and you understood the basic concepts of Generics

(10:38 PM) Robert:

but not some of the finer points (constraints)

(10:39 PM) Robert:

after my hint, i knew that you were familiar with the concept of "design patterns"

(10:39 PM) Daniel:

a lot of information from just a little bit of code

(10:40 PM) Robert:

and now i know that you aren't familiar with the intricacies of C#

(10:40 PM) Robert:

here's the non-obfuscated code:
    static class Singleton<T> where T : new()
    {
        private static T instance = new T();
        public static T Instance
        {
            get { return instance; }
        }
    }

(10:41 PM) Robert:

and now to answer your question...

(10:41 PM) Robert:

first, you have to understand that Singleton<Foo> is a different class than Singleton<Bar>

(10:42 PM) Daniel:

ok

(10:42 PM) Daniel:

seems logical enough

(10:45 PM) Robert:

was looking up some terms i forgot for a second

(10:45 PM) Robert:

Singleton<T> is called an "open" generic type as long as T is undefined

(10:46 PM) Robert:

Singleton<Foo> is a "closed" generic type b/c T has been defined as Foo

(10:46 PM) Daniel:

ok

(10:46 PM) Robert:

Singleton<T> == S<T> from now on

(10:46 PM) Daniel:

ok

(10:47 PM) Robert:

so now that you know S<Foo> is a totally different class than S<Bar>...

(10:47 PM) Robert:

notice that the class is static - both member (field and property) are both static

(10:47 PM) Daniel:

I see

(10:48 PM) Daniel:

so you don't need an instance of the class, but it returns an instance
of T

(10:50 PM) Robert:

    class Foo
    {
        public object bar = new object();
    }
is basically the same as...
    class Foo
    {
        public object bar;
        public Foo()
        {
            bar = new object();
        }
    }

(10:50 PM) Robert:

first initializes bar inline; second initializes bar inside the constructor

(10:51 PM) Daniel:

I'm with you

(10:51 PM) Robert:

first is essentially converted to second when compiled

(10:51 PM) Robert:

C# guarantees that all fields will be initialized before any user-defined ctor code is executed

(10:52 PM) Daniel:

ok

(10:52 PM) Robert:

    class Foo
    {
        public int bar = 3;
        public Foo()
        {
            bar = 2;
        }
    }

(10:52 PM) Robert:

in this case, bar is initialized to 3, then immediatly overwritten with 2

(10:53 PM) Daniel:

I see

(10:53 PM) Robert:

C# also guarantees that a static constructor will be executed exactly one time per class (per AppDomain)

(10:54 PM) Robert:

and that it will be executed immediatly before the first access of any static members of the class

(10:54 PM) Daniel:

does the constructor need an access modifier?

(10:54 PM) Robert:

static constructors can't have access modifiers

(10:55 PM) Robert:

instance constructors follow the same rules as other members - everything without an access modifier is private by default

(10:55 PM) Daniel:

ok
let me soak in what you wrote

(10:57 PM) Daniel:

so its the static keyword in the constructor that makes it the singleton

(10:57 PM) Robert:

the class i sent you doesn't even have an explicit constructor

(10:58 PM) Daniel:

oh, you're right

(10:58 PM) Daniel:

hmm

(10:59 PM) Daniel:

so the fact that its a static class then

(10:59 PM) Robert:

sorta - in C# a static class is just a way to ensure that all members are static
it doesn't mean much

(11:01 PM) Robert:

(in .Net 1.x they shipped with a class that was expected to be "static", but it had a public instance method and the only instance ctor was Private - that meant that there was no way for anyone to instantiate the class and use the public method - in .Net 2.0 they added the concept of a "static class" to prevent things like that in the future)

(11:02 PM) Daniel:

I see

(11:03 PM) Robert:

i have given you all the info you need to answer your orig. question

(11:04 PM) Robert:

(inline initialization == ctor initialization; static ctor is called exactly once and just before first access of any static member)

(11:06 PM) Daniel:

I get it

(11:06 PM) Robert:

you grok it?

(11:06 PM) Daniel:

no, I don't want  to say I grok it until I've used it

(11:07 PM) Daniel:

so pretty much that's how you do a singleton in .net?

(11:08 PM) Daniel:

or is that across other languages as well?

(11:08 PM) Robert:

other languages/platforms have different intricacies
and that's not the normal way to do a singleton
it's my own invention
:)

(11:08 PM) Daniel:

seems elegant

(11:09 PM) Daniel:

although I don't know the other way

(11:09 PM) Daniel:

I have a question for you

(11:10 PM) Daniel:

its C++ but more OOP specific

(11:11 PM) Daniel:

in the main class I'm doing at work, it has a bunch of functions that work with the member  data

(11:12 PM) Daniel:

it basically has one method, and inside that method I've broken tasks down into their own methods

(11:12 PM) Daniel:

but since its all within the class I don't have to pass anything into these methods since I already have access to them

(11:13 PM) Daniel:

but it feels weird or something

(11:13 PM) Robert:

it's a bad habit

(11:13 PM) Daniel:

I thought so, but I wasn't sure

(11:14 PM) Robert:

unless the data (state) needs to be persisted even after the call to the "basically one method" then it should be passed to each method as needed

(11:15 PM) Daniel:

ok, I felt that was the right way
tomorrow I'll fix it

(11:16 PM) Daniel:

I mean I felt that passing parameters was the right way

(11:19 PM) Robert:

this is the conventional singleton pattern
    public class Foo
    {
        // prevents public instantiation
        private Foo() { }
        private static Foo instance;
        public static Foo Instance
        {
            get
            {
                // this is called the "double-checked locking" singleton pattern
                // it attempts to solve a "race condition" that may occur in multi-threaded systems
                if (instance == null)
                {
                    lock (this)
                    {
                        if (instance == null) // another thread could have assigned it since the previous check
                        {
                            instance = new Foo();
                        }
                    }
                }
                return instance;
            }
        }
    }

(11:20 PM) Robert:

http://www.ibm.com/developerworks/java/library/j-dcl.html

(11:21 PM) Robert:

"The bottom line is that double-checked locking, in whatever form, should not be used because you cannot guarantee that it will work on any JVM implementation."
same thing on the .Net platform

(11:23 PM) Robert:

"Listing 10" in that article is "good" but not great in .Net b/c it isn't lazy enough

(11:24 PM) Robert:

access to *any* static member will instantiate the "instance" field even though i may not be using it
anyway, it's bedtime
i think you've got enought for tonight
:)

(11:24 PM) Robert:

i had fun teaching you

(11:24 PM) Daniel:

for sure, thanks

(11:25 PM) Daniel:

interesting how you merged our two topics
did you notice that?

(11:25 PM) Robert:

no?

(11:25 PM) Daniel:

we were talking about design patterns then about programmers you don't like, which lead to my question about how much input you have in the hiring

(11:26 PM) Daniel:

which lead to you giving me the example snippet you wrote for interviewees

(11:26 PM) Robert:

which went back around to patterns

(11:26 PM) Daniel:

which was about a singleton
:0-)
uh, :)

(11:26 PM) Robert:

i'm just good like that :)
goodnight

(11:26 PM) Daniel:

guess so, night