Propertys statt Getter und Setter Methoden?



  • audacia schrieb:

    Jedenfalls wäre ich interessiert, wie du ohne Properties ein Objekt serialisieren und über so etwas wie einen Objektinspektor modifizierbar machen willst. Wenn du da nur Getter und Setter benutzt, mußt du z.B. mindestens eine Konvention für deren Benennung erzwingen

    Ja. Und was spricht dagegen? Machen Java Beans doch auch. Man könnte auch, wie von Dir vorgeschlagen, Annotationen/Attribute verwenden. Alles kein Ding. Solange das Serialisierungs- bzw. Introspektionsframework diese Konvention kennt, ist alles machbar. Und das muss ja nicht zwingend Bestandteil der Sprache sein sondern kann eine freie Bibliothek oder gar ein vollkommen separates Tool (wie Google das mit den Protocol Buffers tut) sein.



  • Konrad Rudolph schrieb:

    Machen Java Beans doch auch.

    IMHO schon ein Argument dagegen. SCNR 😉

    Konrad Rudolph schrieb:

    Man könnte auch, wie von Dir vorgeschlagen, Annotationen/Attribute verwenden. Alles kein Ding.

    Wer bekommt die Attribute? Getter, Setter, beide? Falls letzteres, wie wird mit Redundanz und mit widersprüchlichen Attributen umgegangen? Falls nur einer, welcher?



  • audacia schrieb:

    Konrad Rudolph schrieb:

    Machen Java Beans doch auch.

    IMHO schon ein Argument dagegen. SCNR 😉

    Hehe. Mag sein. Ich bevorzuge ja auch Properties.

    Konrad Rudolph schrieb:

    Man könnte auch, wie von Dir vorgeschlagen, Annotationen/Attribute verwenden. Alles kein Ding.

    Wer bekommt die Attribute? Getter, Setter, beide? Falls letzteres, wie wird mit Redundanz und mit widersprüchlichen Attributen umgegangen? Falls nur einer, welcher?

    Das sind natürlich alles gute Einwände. Wer ein entsprechendes Framwework bastelt, muss sich das gut überlegen. Ich habe keine pauschale Antwort darauf. Ich würde allerdings mal sagen, wenn man Annotations verwendet, dann müssen beide Methoden sowas erhalten (schon deswegen, weil man sonst gleich Namenskonventionen verwenden könnte, und auch, um Properties selektiv read-only zu machen). Man könnte sogar noch einen Schritt weitergehen und ganz andere Konventionen finden, z.B. (in Java) anonyme, verschachtelte Klassen, die von einem „Property“-Interface hergeleitet sind:

    interface ReadOnlyProperty<T> {
        public T get();
    }
    
    interface Property<T> extends ReadOnlyProperty<T> {
        public void set(T value);
    }
    
    class Foo {
        private int _x;
    
        public final Property<Integer> X = new Property<Integer>() {
            public Integer get() { return _x; }
            void set(Integer value) { _x = value; }
        };
    }
    
    Foo f = new Foo();
    f.X.set(42);
    System.out.println(f.X.get());
    

    Ungetestet, so in der Art sollte das aber gehen und ich bin sicher nicht der erste, der auf diesen Trichter kommt.

    /EDIT: getestet, korrigiert, klappt. Hui. Das lasse ich mir patentieren. 😉



  • Und in C++ kann man Properties gut mit Template-Klassen nachbauen:

    // property.h
    
    #ifndef PROPERTY_H
    #define PROPERTY_H
    
    template<typename T> class property_wrapper
    {
    public:
    	explicit property_wrapper(const T& t)
    		: _t(t)
    	{}
    
    	operator T() const { return _t; }
    
    private:
    	const T& _t;
    };
    
    template<typename T> class property_readonly
    {
    public:
    	property_readonly()
    	{}
    	property_readonly(const T& t)
    		: _t(t)
    	{}
    
    	const T& get() const { return _t; }
    
    	const T& operator () () const { return _t; }
    
    	operator T() const { return _t; }
    
    	T& operator = (const property_wrapper<T>& t) { return _t = t; }
    
    protected:
    	void set(const T& t) { _t = t; }
    
    	const T& operator = (const T& t) { _t = t; return t; }
    	const T& operator ()(const T& t) { _t = t; return t; }
    
    	const T& operator += (const T& t) { _t += t; return _t; }
    	const T& operator -= (const T& t) { _t -= t; return _t; }
    
    private:
    	T _t;
    };
    
    template<typename T> class property
    {
    public:
    	property()
    	{}
    	property(const T& t)
    		: _t(t)
    	{}
    
    	const T& get() const { return _t; }
    	void set(const T& t) { _t = t; }
    
    	const T& operator = (const T& t) { _t = t; return t; }
    	const T& operator += (const T& t) { _t += t; return _t; }
    	const T& operator -= (const T& t) { _t -= t; return _t; }
    
    	const T& operator () () const { return _t; }
    	const T& operator () (const T& t) { _t = t; return t; }
    
    	operator T() const { return _t; }
    
    private:
    	T _t;
    };
    
    #endif
    

    Und die Benutzung dann z.B. so:

    void TestProperty()
    {
    	class PropTest
    	{
    	public:
    		PropTest()
    			: x(0), y(0)
    		{}
    
    		void set_y(int value)
    		{
    			y = property_wrapper<int>(value); // only set property with wrapper class
    		}
    
    		property<int> x;
    		property_readonly<int> y;
    	};
    
    	PropTest p;
    
    	p.x.set(0);
    	//p.y.set(1);
    	int x = p.x.get();
    	int y = p.y.get();
    
    	p.x(42);
    	x = p.x();
    
    	p.x = 14;
    	x = p.x;
    	p.x = x;
    
    	//p.y = 13; // no access to protected member
    	//p.y(7);	// same error -> OK
    	p.set_y(7);
    	y = p.y;
    	p.set_y(y);
    }
    

    Ich habe auch noch eine Variante, bei der man die Getter- und Setter-Methode explizit angeben kann...



  • Konrad Rudolph schrieb:

    Das sind natürlich alles gute Einwände. Wer ein entsprechendes Framwework bastelt, muss sich das gut überlegen. Ich habe keine pauschale Antwort darauf. Ich würde allerdings mal sagen, wenn man Annotations verwendet, dann müssen beide Methoden sowas erhalten (schon deswegen, weil man sonst gleich Namenskonventionen verwenden könnte, und auch, um Properties selektiv read-only zu machen).

    Das ist alles schön und gut, führt uns aber nur wieder zurück zu meinem Punkt: der Motivation, so etwas wie Properties in eine Sprache einzuführen. Neben dem Vorteil in der Lesbarkeit, den du ja zu Recht hervorhebst, hat man mit dem Sprachmittel der Properties eine eindeutige, leicht verständliche, redundanzfreie, nicht konventionsbindende Syntax, mittels derer man den Status eines Objektes repräsentieren kann; dies ist meines Wissens der Anlaß für die Einführung von Properties in Delphi gewesen. Daß es etwas schöner aussieht als Getter und Setter, ist ein legitimes Argument für Ästheten (und Sprachdesigner sollten einen Sinn für so etwas haben!), aber es ist nicht das Wesentliche.



  • ich hab jetzt nicht alles gelesen - aber

    wieso behaupten so viele das propertys die kapselung zerstoeren
    man muss ja nicht

    public int X { get; set; }
    

    machen; da stimm ich zu, das ist keine kapselung mehr
    dann macht man eben so

    public int X { get; private set; }
    

    und feddich, schon issses readonly

    oder mal direkt im vergleich
    "herkoemmlich"

    class Bla
    {
        private int _x = 0;
        public int GetX()
        {
            return _x;
        }
        public void SetX(int x)
        {
            _x = x;
        }
    }
    
    //using
    int x = bla.GetX();
    bla.SetX(x);
    

    als property

    class Bla
    {
        private int _x = 0;
        public int X
        {
            get { return _x; }
            set { _x = value; }
        }
    }
    
    //using
    int x = bla.X;
    bla.X = x;
    

    hat man die selbe kapselung und ist im kontex dann deutlich lesbarer

    //edit, class kleingeschrieben, ich mach zZt zu viel vbs #gg



  • Mr Evil schrieb:

    wieso behaupten so viele das propertys die kapselung zerstoeren

    Wer behauptet das?



  • Hah, großartig, audacia!



  • das war algemein gesprochen, nicht auf diesen thread bezogen
    ich les das oefter



  • audacia schrieb:

    Mr Evil schrieb:

    wieso behaupten so viele das propertys die kapselung zerstoeren

    Wer behauptet das?

    Weiss nicht.
    Dumme Leute?


Anmelden zum Antworten