简体   繁体   中英

What's a good pattern for situation when some property should be changed in one way from inside the class, and other way from the outside?

(I'm probably overthinking a pretty simple thing, but nevertheless.)

I have a GUI control with a public property that contains it's current value. The value can be changed from inside in a variety of ways — the control is pretty complicated, and also has children with different behavior. On every such change, there has to be played a sound and an event should be fired off.

On the other hand, it can be changed from outside, by the logic elements; in this case, all GUI components should be updated, but no sound should be played.

So, essentially, I need to use two setters: one for the inside use, and one for the outside. What's the best way to implement this, so that code will be readable and future maintainers won't accidentally confuse the two? (Obviously, they won't be able to use private setter when they should use public, but it could be confusing the other way around).

(I'm currently using C#, but I don't think that there's anything language-specific to this question, so I omit the tag.)

I assume you use an MVVM or MVC model; this is the best way to split the GUI and model (logic elements).

The best way would be to make a public method for outside use, which calls a protected method for inside use. All logic is inside the protected method. However by passing a boolean it is decided to play the sound or not, like:

public void Set(...)
{
    Set(..., False); // False -> No play
}

protected or private Set(..., play = True) // Default: play sound
{
    if (play)
    {
        // Play sound
    }

    // Normal set behavior
}

Of course, it will not stop the public Set being called from inside ... you could change the public Set to a more specific name, like SetWithoutSound, or if you don't want this 'feature' to be specified so directly, make a clear comment in the public Set that the private Set should be used for internal use.

I'd prefer having a single setter method and a method that does something (fires the notification) and changes the value trough the setter:

public void set(Type value)
{
    _member = value;
}
public/protected/private void changeAndNotify(Type value)
{
    set(value);
    playSound();
}

I like it more because you have a complex method that uses the setter instead of setter that uses a complex method which is a better design imho. In addition you don't have conditions to check which makes it more clear.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM