DEV Community

Discussion on: No Sacred Cows: I, Interface

Collapse
 
sam_ferree profile image
Sam Ferree

I'm curious as to the use case for needing to know whether a type is concrete or abstract just by looking at it?

Even if most modern editors couldn't give you this information right away, when would you need to create an instance of a type you know nothing about? when could you hope to do so correctly?

Collapse
 
miketalbot profile image
Mike Talbot ⭐

Not that I totally disagree with the point you make about clarity, but I've always considered specially naming interfaces and abstract classes like this because you cannot create them. I can do new Dictionary but I immediately know I have to look for something to create or be an implementation if it starts with an "I" or an "A"

Thread Thread
 
sam_ferree profile image
Sam Ferree

I think that information is present, but insufficient to determine how you can obtain an instance of a given type.

A class might have a private constructor. In this case an S prefix to signal a struct actually would seem to be useful because it would tell you there has to be a public parameter-less constructor.

But that's not always true either. Consider the Guid type. new Guid() is almost never correct, and what you actually want is Guid.NewGuid().

If IEnumerable were just named Enumerable, would you just new them up? The kind of enumerable you need often depends on the situation. Creating a range happens under different circumstances than creating a List. Knowing that you can't call new IEnumerable is insufficient to tell you how to actually get one.

My point is that there's many things you need to know when trying to instantiate a given type. If you know so little about a type that you aren't sure if it's an interface or a class, then I wonder how you could know how to correctly instantiate it, or even why you need to. And all of this Even If this information wasn't quickly available to us in most modern editors.

Collapse
 
jayjeckel profile image
Jay Jeckel

It isn't about readability at write-time, it's about readability at read-time. Anything that helps me understand the design of the system when I'm reading through the code is useful.

Take your example:

public class SqlBookRepository : BookWriter, BookReader { ... }
Enter fullscreen mode Exit fullscreen mode

That line of code tells me there are two types being used to derive a third type. Is the derived type based on a partial implementation (ie abstract class) and a contract (ie an interface) or is it based on two contracts? Can't tell here, so I'm going to have to dig further into the code to find out. However, a couple additional characters would answer the question without further digging. Is such information useful in toy examples like those in your article, arguably not really. Is it useful when digging through a project with hundreds of files and tens of thousands of lines of code? Yes, yes it is.

If all your doing is writing code, then I can understand finding such prefixes less than useful, but if you spend a major portion of life digging through other's code, then these little bits of context help.

And ultimately, that's the point, providing context about the purpose of a type. The I isn't a Systems Hungarian notation saying the type is implemented as an interface, it's an Apps Hungarian notation saying the type's purpose is as a contract for the api of the derived type.

Thread Thread
 
sam_ferree profile image
Sam Ferree • Edited

Note that your original point was about knowing whether or not you could instantiate something, which is done while writing code, and now you've seemed to switch gears saying it's about reading code.

I think IFF you're working in an editor where the color of abstract classes and interfaces are exactly the same, and where some information about the type doesn't come up when you hover over it and if you can't jump to the relevant file quickly with F12 or some similar keystrokes, THEN it could be useful to have that information.

But if you're working in an environment that limited, all of hungarian notation comes back on the table. What type is this variable? You can't know because you've told me your editor doesn't display that information and you can't jump to it quickly, so by your own argument it makes sense to preface strings with 'sz'

Is this a member variable? You can't know because you've told me your editor doesn't provide that information or a quick way to find it out. So we should provide that information be prefixing member variables with an '_'

So IFF that is your situation and you follow all of Hungarian notation rules, than I would say you're being consistent and writing code for good readability, but if not, then it sounds like cargo cult programming to me.

Thread Thread
 
jayjeckel profile image
Jay Jeckel

Note that your original point was about knowing whether or not you could instantiate something, which is done while writing code, and now you've seemed to switch gears saying it's about reading code.

Ah, I see the confusion. I wasn't suggesting that knowing what is concrete is the purpose of the convention, merely relating that, as I heard it back in the day, instantiable classes were considered the default and that is why non-concrete things get prefixes and instantiable stuff doesn't.

If there is a purpose to it, then that is to tell the coder what the job of the types is. No prefix, the types job is to be instantiated; I prefix, the types job is as a contract; A prefix, the job is as a base partial implementation; etc.

I think IFF you're working in an editor where the color of abstract classes and interfaces are exactly the same, and where some information about the type doesn't come up when you hover over it and if you can't jump to the relevant file quickly with F12 or some similar keystrokes, THEN it could be useful to have that information.

Maybe I'm getting old, but I don't find editor features to be a compelling argument for or against naming conventions. Others' experiene may be different, but I still read a good amount of code daily outside IDEs and the readablity of the code shouldn't be downgrade because it isn't be read in an editor.

But if you're working in an environment that limited, all of hungarian notation comes back on the table. What type is this variable? You can't know because you've told me your editor doesn't display that information and you can't jump to it quickly, so by your own argument it makes sense to preface strings with 'sz'

That's what I was getting at in the last post. The I prefix isn't Systems Hungarian telling you the type is implemented as a interface construct, it is Application Hungarian telling you the type is an API contract. For example, IEntity would be equivalent to EntityContract.

As another example, I don't need to prefix strings with s or other such, because their underlying type isn't what is important, their purpose is important, so their name would have DisplayText, FirstName, or some other descriptive name to make that clear.

Is this a member variable? You can't know because you've told me your editor doesn't provide that information or a quick way to find it out. So we should provide that information be prefixing member variables with an '_'

Yep, in my set of naming conventions, all private member variables are prefixed with _. And at this point it probably won't surprise you to find out that I also enforce the use of this/self scoping when calling member fields, methods, and properties.

So IFF that is your situation and you follow all of Hungarian notation rules, than I would say you're being consistent and writing code for good readability, but if not, then it sounds like cargo cult programming to me.

Yes, I religiously follow very consistent naming conventions and often reevaluate them for the dangers of cargo coding, but these have proved useful to me time and again.