2015-03-05 5 views
1

У меня есть переменная тома, которую я хочу защитить от изменения, если только человек не называет определенную функцию. Есть ли способ сделать это там, где его можно изменить только этой функцией, кроме создания частного класса внутри класса. Я полагаю, что создание частного класса - хорошая идея, но мне было бы интересно, если у кого-то другой подход. AudioPlayer никогда не должен позволять изменять громкость без вызова SetVolume. Это код, который у меня есть здесь, но я задавался вопросом, были ли люди по-другому.Есть ли способ защитить переменную класса от изменения вне функции

public class AudioPlayer 
{ 
    private class VolumeManager 
    { 
     private AudioPlayer mAudioPlayer; 
     public VolumeManager(AudioPlayer audioPlayer) 
     { 
      mAudioPlayer = audioPlayer; 
     } 

     private float volume; 

     public void SetVolume(float _volume) 
     { 
      volume = _volume; 

      //Do other necessary things that must happen when volume is changed 
      //This is the point of the question 
      mAudioPlayer.ModifyChannelVolume(Volume); 
     } 
     public float GetVolume() 
     { 
      return volume; 
     } 
    } 

    private VolumeManager mVolumeManager; 
    public AudioPlayer() 
    { 
     mVolumeManager = new VolumeManager(this); 
    } 

    public void ModifyVolume(float volume) 
    { 
     mVolumeManager.SetVolume(volume); 
    } 
} 
+3

Почему бы просто не сделать объем частным поплавком? – heartyporridge

+2

Я думаю, что частный класс - единственный способ сделать это. Но в этом конкретном случае, почему бы просто не поместить собственный код в сеттер вместо отдельного метода? – Cameron

+0

@Cameron Мне не очень нравится идея setter делать другие вещи, но ваше предложение хорошее и может быть использовано другими. что касается комментария от аналитики, это все равно позволит программисту в моей команде, который не понимает настройки для изменения тома, не вызывая других крючков. – Gandalf458

ответ

3

Проблема, как я вижу, что даже с собственным полем это еще несколько интуитивно и естественно хотят назначить непосредственно в поле. Мы хотим убедиться, что этого не произойдет. В этом случае я рекомендую строить это как собственность, а не поля, а просто быть дисциплинированным о только присваивании свойства:

public class AudioPlayer 
{ 

    public float Volume 
    { 
     get { return _volume_NeverSetThisDirectly;} 
     set 
     { 
      _volume = value; 
      //Do other necessary things that must happen when volume is changed 
      ModifyChannelVolume(_volume_NeverSetThisDirectly); 
     } 
    } 
    [Browsable(false)] 
    [DebuggerBrowsable(DebuggerBrowsableState.Never)] 
    [EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] 
    private float _volume_NeverSetThisDirectly; //Never assign to this directly! 
} 

Это не жизнь это до такой степени, что вы просите , но он действительно переворачивает интуитивно понятный и естественный способ, которым кто-то будет работать в этом классе, чтобы использовать значение правильно, а не наоборот. Это также чертовски много меньше кода и сложности для поддержания. Добавление атрибутов в значительной степени не повлияет на вещи для тех, кто работает в этом классе уже, но поскольку мы переходим на использование социального давления, а не технических запретов, тем больше предупреждающих знаков у нас есть, тем лучше.

Это также дает вам возможность открыть в будущем, когда вы обнаружите, что один странный случай, когда вы хотите изменить поле тома без всякого другого происшествия, что вы можете сделать это, не делая при этом странных вещей частный экземпляр класса.

+0

Я нахожусь в команде многих людей, работающих быстро. Ожидая, что каждый программист читает все комментарии, когда под временным ограничением бесполезно. :( – Gandalf458

+0

@ Gandalf458 Это не про комментарий. Речь идет о том, «Кто действительно будет использовать' _volume', когда 'Volume' появляется более естественно» ... особенно если вы спрячете поле из своих подсказок intellisense. , вы можете даже изменить имя '_volume' на что-то вроде' _volumeNeverSetDirectly'. –

+0

На самом деле, я думаю, я добавлю это к ответу. –

0

Может быть, вы можете объявить переменную тома как частные, и только модифицировали переменную внутри функции, и использовать свойство, чтобы выставить в поле Громкость.

private float Volume; 
public float pVolume 
    { 
     get 
     { 
      return Volume; 
     } 
    } 
+1

У ОП уже есть 'частный набор'. – user2864740

Смежные вопросы