Wie benennt Ihr Interface-Klassen?
-
@finix! i_button habe ich auch schon dran gedacht. Fand ich aber immer irgendwie optisch komisch. Dieses verdammte Apple würde mir nicht aus dem Kopf gehen... i_mac, i_pod usw.
@asc! OK, das mit dem zu viel tippen war etwas spaßig gemeint. Ich benutze selber sogar VisualAssistX. Aber lange Namen sehen auch optisch nicht gut aus... kann den Sourcecode unleserlich machen. (zu kurze Namen natürlich auch!) Also, es steckt meiner Meinung nach schon ein Stück Wahrheit dahinter... auch wenn ich das mit dem Tippen nicht ganz ernst meinte.
interface_button liesse sich besser sortieren als button_interface... stimmt. button_interface spricht sich aber besser.
@devil!
Darauf bin ich ja garnicht gekommen!!! Sieht fast so aus, als ob ich noch was zu refectorn habe!!! Wobei inteface:: der Optimalfall ist. Sieht ja dann doch eher so aus:
class button : public mylib::interface::button { }; void foo(mylib::interface::button b) { }
Der Interface-Namespace hat auf jeden Fall seinen Reiz!!!
Werde mal schauen was hier noch für Ideen, Ablehnungen oder Zustimmungen kommen. Finde nämlich Benamsung von Typen garnicht so unwichtig für eine Library.
-
Bist du denn sicher, dass du einen base_button und einen button brauchst, die beide noch keine konkreten Typen sind? Was hat denn ein button für eine Funktionalität, die ein base_button nicht hat?
Achso und wegen der Benamsung (schönes Wort :)) bin ich für IButtonEgal was du schlussendlich nimmst, bitte nicht i_button, das sieht gar schröcklich aus!
-
@Artchi: Naja kommt darauf an:
namespace mylib { namespace interface { class button { }; }; // ... class bitmap_button : public interface::button {}; void show_buttons(std::ostream& out, std::vector<interface::button*> const& data) { for (std::size_t i(0); i < data.size(); ++i) out << data[i] << std::endl; } };
... aber ist natürlich klar, es geht von idealfällen aus ... ^^
-
Badestrand schrieb:
Bist du denn sicher, dass du einen base_button und einen button brauchst, die beide noch keine konkreten Typen sind? Was hat denn ein button für eine Funktionalität, die ein base_button nicht hat?
Richtig, der button (aus meinem ersten Posting) hat tatsächlich nicht mehr öffentliche Schnittstellen. Aber er implementiert schon ein paar Schnittstellen, und Eigenschaften, die ich für z.B. default_button, radiobutton und checkbox brauche. Und lässt nur ein paar spezielle Schnittstellen unimplementiert, die die drei Buttons unterscheiden.
Zur Zeit habe ich button weg genommen, und nur noch base_button. Aber ich mußte mühsam den selben Code und Attribute in den drei konkreten Buttons implementieren. base_button ist ja nur ein Interface.
Mit den drei Ebenen bin ich flexibler: ich kann eine abstrakte Basis-Implementierung (button) anbieten. Andererseits kann auch jeder, der damit nichts anfangen kann, einfach base_button nehmen. Die Schnittstelle ist immer gleich.
Badestrand schrieb:
Achso und wegen der Benamsung (schönes Wort :)) bin ich für IButton
Egal was du schlussendlich nimmst, bitte nicht i_button, das sieht gar schröcklich aus!
Finde ich auch.:D
-
devil! Ja, innerhalb der mylib ist das auf jeden Fall i.O. Aber wenn jemand mylib benutzt, kann es schon lang werden. Gerade dann, wenn man Schnittstellen für Parameter benutzen sollte.
Vielleicht sollte ich es umgekehrt machen?
namespace mylib { // Interface class button {}; // spec = specialized namespace spec { // abstrakt oder konkret class button {}; } }
Dann braucht man den langen Namespace nur noch, wenn man Objekte instanziert. Bei Parametern benutzt man autom. den kurzen Namespace.
-
wisst ihr eigentlich, dass (D)evil 15 Jahre alt ist?
-
Also so generell würde ich bei einer Hierarchie den Namen von oben nach unten länger werden lassen, also ganz oben schonmal "Button" bzw "button" hinpacken. Bei der mittleren Ebene kommt's halt drauf an, was sie von der oberen unterscheidet, sonst halt "SpecificButton" bzw "spec_button" und dadrunter halt "DefButton" bzw "default_button".
Kurze Nebenfrage: Wie benennst du längere Variablen eigentlich? Nur aus Interesse
-
@wissender:
Wisst ihr eigentlich, dass (D)Evil 15 Jahre alt ist?
Wenn es so wäre, würde es dann ein Problem für dich darstellen?
Kurze Nebenfrage: Wie benennst du längere Variablen eigentlich? Nur aus Interesse
Wen meinst de?
Gerade dann, wenn man Schnittstellen für Parameter benutzen sollte.
namespace interface = mylib::interface; interface::button inst(interface::button::my_enum_val1);
Na ok hast recht ^^ Wird doch relativ lang ...
-
(D)Evil schrieb:
Kurze Nebenfrage: Wie benennst du längere Variablen eigentlich? Nur aus Interesse
Wen meinst de?
Meinte Artchi, weil er seine Klassen irgendwie nach dem Stil benennt, wie ich meine Variablen
-
@badestrand! Ich habe hauptsächlich lange Variablennamen, wenn ich z.B. für einen Button eine spezielle Implementierung habe:
class button : public base_button { native::native_component<button, base_panel, rect_t> *button_impl; rect_t rect; dimension_t dim; std::string name; };
Aber ansonst heißen meine Variablen, ganz normal. Zu lange Variablen mache ich einfach kurz (schneide sie ab oder sowas).
Bei lokalen temporären Variablen, gehe ich meistens noch radikaler vor:layout_ptr fl(new flow_layout()); get_root_panel().set_layout(fl);
@devil! Ja, ich mache ja z.B. sowas:
void foo(mylib::interface::button b);
In einem Header, wo man using namespace vermeiden sollte, wäre das nicht schön.
Aber:
namespace interf = mylib::interface; void foo(interf::button b);
wäre eine gute Lösung. Gute Idee devil!
-
(D)evil schrieb:
Wenn es so wäre, würde es dann ein Problem für dich darstellen?
Nein, im Gegenteil! Ich habe mich nur gewundert, als ich erfahren habe, dass du 15 Jahre alt bist. Ich hätte dich wesentlich älter eingeschätzt.
-
ich persönlich mach keinen unterschied in der benennung zwischen interfaces, abstrakten klassen und konkreten klassen, da es für die verwendung keine rolle spielt. wenn man ausversehen versuchen sollte, eine instanz eines interfaces zu erzeugen, gibt einem der compiler schon früh genug einen auf die finger.
ich mags halt nicht, wenn in den signaturen meiner methoden son präfix gerümpel auftaucht
-
So, jetzt muss ich mich auch mal einmischen. Die Idee mit den Namensbereichen hat natürlich seinen Reiz, ich halte sie trotzdem für nicht sehr gut. Namensbereiche sollten IMHO *thematisch* gruppieren. Ich verwende in C++ eigentlich durchgängig dieselbe Praxis wie in anderen Umgebungen (.NET, Java) auch, also die Konvention
firmenname::projektname
als Präfix für alle Namensbereiche. Der Firmenname kann manchmal weggelassen werden. Namensbereiche haben damit nur zwei Ziele:1. Namenskonflikte verhindern!
2. (Eventuell) Objekte leichter auffindbar machen.Ich denke, ein Namensbereich namens
interface
hilft da nicht (zumal einige alte Compiler immer noch Probleme mit zu vielen verschachtelten Namensbereichen haben).Was lange Namen betrifft: Wo ist das Problem? Wenn ein langer Name nötig ist, um den Zweck einer Methode (o.ä.) ausreichend zu beschreiben, dann wird eben ein langer Name verwendet. In einem aktuellen Projekt (nicht C++) habe ich z.B. eine Klasse namens 'ActionDataSourceControl' und eine Methode namens 'CreateConditionGroupForFields'. Allerdings haben lokale Variablen bei mir eigentlich immer kurze Namen, oft nur einen einzigen Buchstaben. Für kurze Methoden ist das überhaupt kein Problem, bei längeren Methoden verkleinere ich den Gültigkeitsbereich der Variable so weit wie möglich). Außerdem bestehen lokale Variablen bei mir oft aus den Anfangsbuchstaben. Eine lokale Instanz der obenstehenden Klasse könnte bei mir z.B. 'adsc' heißen.
Ansonsten halte ich es wie Archie: Ich verwende konsistent die Benennung, die die STL und Boost vorgeben, also alles Kleinbuchstaben und Unterstrich als Trenner. Das ist zwar keine schöne Konvention (zumindest für öffentliche Schnittstellen), aber Konsistenz ist hier m.E. wichtiger.
Zum Schluss noch einen Satz zur eigentlichen Fragestellung: Ich halte die verwendete Konvention für gut. Aus 'button_base' ist zwar nicht erkennbar, ob es sich um eine Schnittstelle oder eine abstrakte Basisklasse handelt, aber das soll es IMHO auch gar nicht (zumal C++ technisch sowieso nicht zwischen den beiden unterscheiden kann).
-
warum so viele leute probleme mit langen klassen- und methodennamen haben, kann ich ehrlich gesagt immer noch nicht nachvollziehen. lange, beschreibende namen sorgen für sehr viel mehr übersicht, als es die verwendung kurzer namen zum zwecke der "übersichtlichkeit" im code je erreichen könnte.
Glyph *paragraph = new Paragraph; DocumentLayoutContentController *controller = new DocumentLayoutContentController( Layout::PLAIN ); controller->addGlyph( paragraph ); // find ich z.b. wesentlich übersichtlicher als glyph *p = new para; ctrl_doclay *ctrl = new ctrl_doclay( consts::L_PLAIN ); ctrl->add( p );
(das war ein leicht angepasstes reales beispiel ^^)
-
von den ganzen unterstrichen in dem code krieg ich noch augenkrebs. Das ist ja schrecklich. Wie kann man soetwas nur übersichtlicher finden???
-
Konrad Rudolph schrieb:
So, jetzt muss ich mich auch mal einmischen. Die Idee mit den Namensbereichen hat natürlich seinen Reiz, ich halte sie trotzdem für nicht sehr gut. Namensbereiche sollten IMHO *thematisch* gruppieren. Ich verwende in C++ eigentlich durchgängig dieselbe Praxis wie in anderen Umgebungen (.NET, Java) auch, also die Konvention
firmenname::projektname
als Präfix für alle Namensbereiche. Der Firmenname kann manchmal weggelassen werden. Namensbereiche haben damit nur zwei Ziele:1. Namenskonflikte verhindern!
2. (Eventuell) Objekte leichter auffindbar machen.Ich denke, ein Namensbereich namens
interface
hilft da nicht (zumal einige alte Compiler immer noch Probleme mit zu vielen verschachtelten Namensbereichen haben).Ich dachte schon ich bin der einzige der das komisch findet
-
Konrad Rudolph schrieb:
So, jetzt muss ich mich auch mal einmischen.
Ich bitte darum!
Konrad Rudolph schrieb:
Namensbereiche haben damit nur zwei Ziele:
1. Namenskonflikte verhindern!
2. (Eventuell) Objekte leichter auffindbar machen.Ja, beides kann der Namespace interface erfüllen. Auch thematisch erfüllt er seinen Zweck. Klar, es kommt darauf an, was thematisiert werden soll. Ich muß ehrlich sagen, das in unserem aktuellen Java-Projekt, sich die Kräfte durchgesetzt haben, für jeden Pups ein Package anzulegen. Da würde ich am liebsten um mich schlagen:
de.firma.mylib.option de.firma.mylib.option.core de.firma.mylib.option.model de.firma.mylib.option.model.internal de.firma.mylib.option.ui de.firma.mylib.option.ui.internal de.firma.mylib.option.util
Und es ist kein Ende abzusehen. Zumal option nur ein Thema von ca. 30 ist.
Da gehe ich mit dir konform, das sowas nicht ausarten darf.
Konrad Rudolph schrieb:
Ich denke, ein Namensbereich namens
interface
hilft da nicht (zumal einige alte Compiler immer noch Probleme mit zu vielen verschachtelten Namensbereichen haben).OK, in meiner Lib interessieren mich zu alte Compiler nicht. Die schliesse ich sogar absichtlich aus. Ich finde, man darf ein gewisses Mass an Konformität erwrten.
Konrad Rudolph schrieb:
Was lange Namen betrifft: Wo ist das Problem? Wenn ein langer Name nötig ist, um den Zweck einer Methode (o.ä.) ausreichend zu beschreiben, dann wird eben ein langer Name verwendet. In einem aktuellen Projekt (nicht C++) habe ich z.B. eine Klasse namens 'ActionDataSourceControl' und eine Methode namens 'CreateConditionGroupForFields'.
Gegen aussagekräftige Namen habe ich nicht. Aber dein Methodenbeispiel, würde mich mal interessieren. Ich schätz es sieht ca. so aus:
ConditionGroup CreateConditionGroupForFields(Fields f);
Da muß ich sagen, finde ich es unnötig lang. So wäre es kürzbar, und trotzdem verständlich:
ConditionGroup CreateConditionGroup(Fields f);
Der Übergabeparameter kann schon aussagen, das was ich "für" machen soll. Ich sehe öffters solche doppelt-gemoppelt-Bezeichner. Dabei gibt die Signatur-Syntax schon vieles her.
Klar, sowas ist dagegen einfach unschön:
ConditionGroup CrtCndtonGrp(Fields f);
Konrad Rudolph schrieb:
Ansonsten halte ich es wie Archie: Ich verwende konsistent die Benennung, die die STL und Boost vorgeben, also alles Kleinbuchstaben und Unterstrich als Trenner. Das ist zwar keine schöne Konvention (zumindest für öffentliche Schnittstellen), aber Konsistenz ist hier m.E. wichtiger.
*zustimm* Das CamelCase von Java finde ich pers. auch schöner. Aber wenn ich ausgiebig die C++-Stdlib und Boost benutze, halte ich mich an deren Konventionen. Denn in Java richte ich mich auch nach der Sun-Konvention, egal obs mir gefällt oder nicht.
Konrad Rudolph schrieb:
Zum Schluss noch einen Satz zur eigentlichen Fragestellung: Ich halte die verwendete Konvention für gut. Aus 'button_base' ist zwar nicht erkennbar, ob es sich um eine Schnittstelle oder eine abstrakte Basisklasse handelt, aber das soll es IMHO auch gar nicht (zumal C++ technisch sowieso nicht zwischen den beiden unterscheiden kann).
Stimmt, haste Recht. Technisch gesehen ist es in C++ egal ob es abstrakt oder ein "Interface" ist.
-
thordk schrieb:
warum so viele leute probleme mit langen klassen- und methodennamen haben, kann ich ehrlich gesagt immer noch nicht nachvollziehen. lange, beschreibende namen sorgen für sehr viel mehr übersicht, als es die verwendung kurzer namen zum zwecke der "übersichtlichkeit" im code je erreichen könnte.
Glyph *paragraph = new Paragraph; DocumentLayoutContentController *controller = new DocumentLayoutContentController( Layout::PLAIN ); controller->addGlyph( paragraph ); // find ich z.b. wesentlich übersichtlicher als glyph *p = new para; ctrl_doclay *ctrl = new ctrl_doclay( consts::L_PLAIN ); ctrl->add( p );
(das war ein leicht angepasstes reales beispiel ^^)
ctrl anstatt Controller finde ich für eine Variable i.O. Zumal ctrl auch noch auf jeder (englischen) Tastatur drauf steht, und jeder wissen sollte was es heißen könnte.
Im Ernst, solche Zerstückelungen mache ich pers. hauptsächlich bei Variablen und dann meistens nur bei temporären.
ctrl_doclay als Typname würde ich so auch nicht machen. Höchstens bei privaten lokalen Klassen, die nicht nach draussen dringen. Alles was vor dem User versteckt ist, kürze ich gerne. Alles was der User benutzen muß, versuche ich kurz zu halten. Aber nicht in dem versuche Buchstaben weg zu lassen.
Anstatt TreeListView finde ich z.B. TreeList i.O., wenn es in einem View-Namespace ist. Wenn es ein TreeListModel gibt, sollte man evtl. einen Model-Namespace überlegen. Wobei TreeListView auch schon recht kurz ist. Nur noch mehr Wörter dürften nicht rein. StuecklistenTreeListView finde ich schon har an der Grenze! Noch ein Wort, und ich würde die Kriese kriegen.
-
Artchi schrieb:
Konrad Rudolph schrieb:
Was lange Namen betrifft: Wo ist das Problem? Wenn ein langer Name nötig ist, um den Zweck einer Methode (o.ä.) ausreichend zu beschreiben, dann wird eben ein langer Name verwendet. In einem aktuellen Projekt (nicht C++) habe ich z.B. eine Klasse namens 'ActionDataSourceControl' und eine Methode namens 'CreateConditionGroupForFields'.
Gegen aussagekräftige Namen habe ich nicht. Aber dein Methodenbeispiel, würde mich mal interessieren. Ich schätz es sieht ca. so aus:
ConditionGroup CreateConditionGroupForFields(Fields f);
Da muß ich sagen, finde ich es unnötig lang. So wäre es kürzbar, und trotzdem verständlich:
ConditionGroup CreateConditionGroup(Fields f);
Der Übergabeparameter kann schon aussagen, das was ich "für" machen soll. Ich sehe öffters solche doppelt-gemoppelt-Bezeichner. Dabei gibt die Signatur-Syntax schon vieles her.
Da gebe ich Dir vollommen recht. Leider sieht die Signatur vollkommen anders aus als von Dir vermutet:
public static void CreateConditionGroupForFields( WizardBase dialog, StepBase step );
Hier schreit ja erst einmal alles nach schlechtem Design. Leider gibt es dafür recht gute Gründe. 'WizardBase' ist eine (Dialog-)Basisklasse aus einem anderen Projekt. Die Methode mit dem Monsternamen befindet sich in einer statischen Helper-Klasse und stellt quasi ein Mixin dar. Eine Member-Methode wäre hier konzeptuell besser gewesen, kommt aber leider nicht in Frage, weil die Vererbungshierarchie sonst ausgeartet wäre (na ja, um genau zu sein ist fehlende Planung Schuld, es wäre einiges Refactoring notwendig gewesen, um das nachträglich zu korrigieren). Bei der im Namen genannten 'ConditionGroup' handelt es sich um ein UI-Konzept aus der Anwendung. Die 'Fields' sind Teil der 'StepBase'-Klasse (nicht ganz korrekt, aber nahe genug). Elemente der Klasse 'Field' direkt zu übergeben ist leider auch nicht möglich, weil diese nicht direkt existieren sondern durch diese Methode erst extrahiert werden.
=> Aber im Prinzip hattest Du schon recht: Dieser umständliche Name kompensiert in großem Maße für ein schlechtes Design.
*zustimm* Das CamelCase von Java finde ich pers. auch schöner.
*brr*. CamelCase ist für mich persönlich das schlimmste überhaupt; es stört den Lesefluss. Herfried Wagner hat das recht anschaulich erläutert (runterscrollen bis „Probleme der Camel Case-Konvention“).
Ich bevorzuge aus diesem Grund für öffentliche Schnittstellen die PascalCase-Konvention. Aber wie Du auch sagtest: Ich halte mich an die „lokalen Gepflogenheiten“, d.h. in Java verwende ich z.B. ebenfalls CamelCase.
-
die in dem artikel erläuterten probleme betreffen aber auch ausschließlich die betrachtete sprache und nicht java, die sprache, welche camel case populär gemacht hat.
public int foo; public foo(); //... this.foo = 0; // ist *immer* eindeutig foo = 0; // ebenso foo(); // und zwar deshalb foo() = 0; // und weil sowas falsche syntax wäre ;)