Prefix I für ein Interface
-
ich find das fehlende C vor den Klassen schade, aber was solls.
-
Ich würde mich so sehr darüber aufregen, aber es ist ein Implementatierungsdetail, ob ich ein Interface verwende. Was, wenn ich morgen anstelle des Interfaces eine Klasse anbieten? Dann muss man überall das IFoo in Foo umbenennen, was überhaupt nicht nötig wäre.
Die Javarianer-Variante: Interfaces heissen einfach nur "List", "File" etc., Implementierungen heissen XxxList/XxxFile, wobei Xxx etwas ist was Aufschluss über die Art/Besonderheiten der Implementierung gibt. Das führt dann zu so eigenartigen Namen wie ArrayList.
Wieso eigenartig? Du hast das List Interface und du hast eine Listenimplementiering, die auf einem Array beruht. Also ist es ein ArrayList. Eine LinkedList ist eine Liste, die verkettet ist. Besser als wie im .NET Framework, da ist die Beschreibung von IList und List identisch, ich weis nicht wie List das IList Interface implementiert. Im Java Framework ist es nach dem Namen sofort ersichtlich. Wenn du eine Standard-Implementierung hast, ist es besser die Klasse mit "DefaultFoo" oder "FooImp" zu versehen. Die Klasse siehst du im Code nur einmal, das Interface wird aber immer wieder verwendet.
Was die Interface Namen angeht auch alles schön kurz: "List<File>" -> supi. Allerdings ist nicht klar ersichtlich was nun ein Interface ist und was nicht. Ob das nun ein Nachteil ist oder nicht ist Ansichtssache, darüber will ich mich mal nicht auslassen. Kommt IMO auch stark drauf an, wie gut man ein Framework schon kennt. Wenn ich 95% der wichtigsten Interfaces namentlich kenne, ist es vermutlich egal. Weiterer Nachteil: diese Regelung ist viel "schwammiger" als die "jedes Interface fängt mit I an" Variante. Einige Klassen implementieren mehr als nur ein Interface, und manchmal ist auch nicht 100% klar welches als das "primäre" Interface angesehen werden kann, nach dem die Klasse benannt werden sollte. Zusätzlich führt es zu Problemen wenn Interfaces nachträglich eingeführt werden.
Wenn die ArrayList Klasse zu einem Zeitpunkte geschrieben worden wäre wo es noch kein List Interface gegeben hat, hätte sie sicher einen anderen Namen bekommen - z.B. einfach nur Array oder DynamicArray. Führt man nachträglich das Interface List ein, dann hat die Klasse auf einmal den falschen Namen.Man sollte immer nach dem Interface programmieren, erst sollte man das Interface klar definieren und danach sollte man seine Klassen implementieren. Das Java Framework wurde offensichtlich danach implementiert, wärend beim C# Framework man zuerst eine Liste programmiert hat und danach das Interface extrahiert hat. Dann wusste man nicht mehr wie man das Interface nennen sollte und hat aus Faulheit ein I Präfix gewählt. (ist meine Spekulation)
Aus "Clean Code A Handbook of Agile Software Craftmanship, Robert C. Martin"
[...]For example, say you are building an Abstract Factory for the creation of shapes. What should you name them? IShapeFactory and ShapeFactory? I prefer to leave interfaces unadorned. The preceding I, so common in today's legacy wads, is a distraction at best and too much information at worst. I don't want my users knowing that I'm handling them an interface. I just want them to know that it's a ShapeFactory. So If I must encode either the interface or the implementation, I choose the implementation. Calling it ShapeFactoryImp, or even hideous CShapeFactory, is preferable to encoding the interface.
Noch ein paar Zitate:
KRZYSZTOF CWALINA: One of the few prefixes used is “I” for interfaces (as in ICollection), but that is for historical reasons. In retrospect, I think it would have been better to use regular type names. In a majority of the cases developers don’t care that something is an interface and not an abstract class, for example.
BRAD ABRAMS: On the other hand, the “I” prefix on interfaces is a clear recognition of the influence of COM (and Java) on the .NET Framework. COM popularized, even institutionalized, the notation that interfaces begin with “I.” Although we discussed diverging from this historic pattern we decided to carry forward the pattern as so many of our users were already familiar with COM.
JEFFREY RICHTER: Personally, I like the “I” prefix and I wish we had more stuff like this. Little one-character prefixes go a long way toward keeping code terse and yet descriptive. As I said earlier, I use prefixes for my private type fields because I find this very useful.
BRENT RECTOR Note: this is really another application of Hungarian notation (though one without the disadvantages of the notation's use in variable names).
-
DEvent schrieb:
Was, wenn ich morgen anstelle des Interfaces eine Klasse anbieten?
Warum sollte man DAS tun? Dass man eine konkrete implementierung durch ein interface ersetzt ist üblich. Den umgekehrten weg zu gehen ist eher sinnlos.
Abgesehen davon... wenn du den typ des angebotenen objects änderst, dann musst du die bezeichner so oder so ändern. Da spielt das I dann keine rolle. Wenn hingegen das interface sämtliche funktionen deines objects abdeckt, ist ein unbenennen von IList zu List absolut unnötig.
-
DEvent schrieb:
Ich würde mich so sehr darüber aufregen, aber es ist ein Implementatierungsdetail, ob ich ein Interface verwende. Was, wenn ich morgen anstelle des Interfaces eine Klasse anbieten? Dann muss man überall das IFoo in Foo umbenennen, was überhaupt nicht nötig wäre.
1. Frage: Wie oft passiert das?
2. Frage: Wie schnell ist das automatische Name-Refactoring der IDE durch?DEvent schrieb:
Man sollte immer nach dem Interface programmieren, erst sollte man das Interface klar definieren und danach sollte man seine Klassen implementieren. Das Java Framework wurde offensichtlich danach implementiert, wärend beim C# Framework man zuerst eine Liste programmiert hat und danach das Interface extrahiert hat. Dann wusste man nicht mehr wie man das Interface nennen sollte und hat aus Faulheit ein I Präfix gewählt. (ist meine Spekulation)
rofl! Also DEvent wirklich, damit machst du dich ja schlicht nur lächerlich. Das ist keine Spekulation sondern reines und typisches MS-Bashing. Man kann das nämlich grob so zusammenfassen: Java ist ein voll gutes und durchdachtes Framework, während sich Microsoft bei .Net überhaupt nichts gedacht hat!
Und was willst du mit den Zitaten aussagen? Grundsätzlich sollte da wunderbar herauskommen, dass es eben eine subjektive Angelegenheit ist.
Grüssli
-
Die Javarianer-Variante: Interfaces heissen einfach nur "List", "File" etc., Implementierungen heissen XxxList/XxxFile, wobei Xxx etwas ist was Aufschluss über die Art/Besonderheiten der Implementierung gibt. Das führt dann zu so eigenartigen Namen wie ArrayList.
Wieso eigenartig?
Wel aus C und C++ Sicht Liste und Array zwei orthogonale Konzepte sind. Unter Liste versteht man eine verkettete solche. Das verträgt sich nicht mit dem Begriff Array, der ja einen zusammenhängenden Speicherblock beschreibt.
Dadurch verwirrte mich QList aus QT auch zuerst. Das ist aus C++ Sicht nämlich gar keine Liste sondern eine deque.
-
Dravere schrieb:
2. Frage: Wie schnell ist das automatische Name-Refactoring der IDE durch?
3 versionen? 5?
schwer zu sagen wann der letzte client code angepasst wurde. ich würde etwa 2-3 Jahre schätzen...interfaces darf man nicht mehr ändern wenn sie mal fix sind.
-
DEvent schrieb:
Ich verstehe nicht wieso man in C# ein Interface speziell auszeichnet.
Dann frage es in http://www.c-plusplus.net/forum/viewforum-var-f-is-28.html
Genauer, ich verstehe nicht, wieso ist es wichtig zu wissen, dass etwas ein Interface ist und keine Klasse.
Da Du hier gefragt hast: Es hängt von der verwendeten Sprache ab.
-
Artchi schrieb:
Das hat doch nichts mit C# und MS zu tun. Ist doch mal wieder so ein typischer MS-Basher Posting.
Hast du was anderes von unserem Linux-Nerd #1 erwartet?
-
mit einer reinen OO-Sprache ("alles ist ein Objekt ... jedes Objekt ist Mitglied einer Klasse") wäre das nicht passiert.
-
Frag mich bloss, was man bei Generische Komposition machen soll
public interface ISystem<F, B> { F Frontend { get; set; } B Backend { get; set; } void Compute(); } public class DefaultSystem<F, B> : ISystem<F, B> { // Use fucking new Syntax for initialization example: new DefaultSystem() { Frontend = ...}; private F frontend; private B backend; public F Frontend { get { return frontend; } set { frontend = value; } } public B Backend { get { return backend; } set { backend = value; } } public virtual void Compute() { } } public class NormalSystem : DefaultSystem<DefaultFrontend, DefaultBackend> { public NormalSystem() : base() { Frontend = new DefaultFrontend(); Backend = new DefaultBackend(); } public override void Compute() { Frontend.front(); Backend.back(); } } public class ReverseSystem : DefaultSystem<DefaultFrontend, DefaultBackend> { public ReverseSystem() : base() { Frontend = new DefaultFrontend(); Backend = new DefaultBackend(); } public override void Compute() { Backend.back(); Frontend.front(); } } public interface IBackend { void back(); } public class DefaultBackend : IBackend { public void back() { System.Console.WriteLine("It's from Backend"); } } public interface IFrontend { void front(); } public class DefaultFrontend : IFrontend { public void front() { System.Console.WriteLine("It's from Frontend"); } } public class Program { static void Main(string[] args) { var sys1 = new NormalSystem(); var sys2 = new ReverseSystem(); sys1.Compute(); sys2.Compute(); Console.ReadLine(); } }