I made some custom control named Range Control in Unity. It has two buttons a plus and a minus and an input field that shows the current value. The control has (for now) two implementations:None-List - The value is clamped between a min and a max.Using a List - The control accepts a range (list) of values and changing the index (much like a dropdown).Both implementation has almost identical UI (on the 2nd one the input field is read only cause you get a range from the outside).I want to make one control of the two. One prefab with one script and let the user decide if it will work like #1 or #2 (or #3 if the future holds).This is what I have by now. How can I make it better?public class RangeControlBase : MonoBehaviour{    public InputField NumberInputfield;    public string m_sPrefix;    public string m_sSuffix;    public RangeControlType RangeType;    public Button PlusButton;    public Button MinusButton;    void Awake()    {        PlusButton.onClick.AddListener(() => ChangeValue(1));        MinusButton.onClick.AddListener(() => ChangeValue(-1));    }    public string Prefix    {        get        {            return m_sPrefix;        }        set        {            m_sPrefix = value;            UpdateValue();        }    }    public string Suffix    {        get        {            return m_sSuffix;        }        set        {            m_sSuffix = value;            UpdateValue();        }    }    public virtual void ChangeValue(int direction)    {        throw new NotImplementedException();    }    public virtual void UpdateValue()    {        throw new NotImplementedException();    }}Range Control:public class RangeControl : RangeControlBase{    public float Stepping = 5;    float m_fMinRange = 10;    float m_fMaxRange = 1000;    float m_fValue;    public Action<float> OnValueChanged = delegate { };    void Start()    {        NumberInputfield.onEndEdit.AddListener(t => SetStringValue(t));    }    public void SetStringValue(string text)    {        float value;        text = Regex.Replace(text, string.Format(@\({0}|{1}\), Prefix, Suffix), string.Empty);        if (float.TryParse(text, out value))        {            Value = value;        }    }    public float Value    {        get { return m_fValue; }        set        {            m_fValue = value;            UpdateValue();        }    }    public float MinRange    {        get { return m_fMinRange; }        set        {            m_fMinRange = value;            UpdateValue();        }    }    public float MaxRange    {        get { return m_fMaxRange; }        set        {            m_fMaxRange = value;            UpdateValue();        }    }    public override void ChangeValue(int direction)    {        Value += direction * Stepping;    }    public override void UpdateValue()    {        m_fValue = Mathf.Clamp(Value, MinRange, MaxRange);        NumberInputfield.text = string.Format({0}{1}{2}, Prefix, m_fValue, Suffix);        MinusButton.interactable = m_fValue != m_fMinRange;        PlusButton.interactable = m_fValue != m_fMaxRange;        OnValueChanged(m_fValue);    }}List Range Control:public class ListRangeControl : RangeControlBase{    public Action<int> OnSelectedIndexChanged = delegate { };    public Action<float> OnValueChanged = delegate { };    List<float> m_itemsList;    int m_iIndex = -1;    public List<float> ItemsList    {        get        {            return m_itemsList;        }        set        {            m_itemsList = value;            m_iIndex = 0;            UpdateValue();        }    }    public int Index    {        set        {            m_iIndex = value;            UpdateValue();        }    }    public override void ChangeValue(int direction)    {        m_iIndex += direction;        OnSelectedIndexChanged(m_iIndex);        UpdateValue();    }    public override void UpdateValue()    {        if (m_iIndex < 0 || m_iIndex > m_itemsList.Count)        {            return;        }        float value = m_itemsList[m_iIndex];        NumberInputfield.text = string.Format({0}{1}{2}, Prefix, value, Suffix);        MinusButton.interactable = m_iIndex > 0;        PlusButton.interactable = m_iIndex < m_itemsList.Count - 1;        OnValueChanged(value);    }}Test Script:public class TestRangeControls : MonoBehaviour{    public RangeControl RangeControl;    public ListRangeControl ListRange;    void Start()    {        //Set Range Control        RangeControl.OnValueChanged += v => { Debug.Log(Selected value is:  + v); };        RangeControl.MinRange = 200;        RangeControl.MaxRange = 2000;        RangeControl.Stepping = 50;        RangeControl.Value = Mathf.RoundToInt(Random.Range(RangeControl.MinRange, RangeControl.MaxRange));        //Set List Range Control        ListRange.OnSelectedIndexChanged += i => { Debug.Log(Selected index is:  + i); };        List<float> numList = new List<float>();        for (int i = 1; i < 11; i++)        {            numList.Add(i * 100);        }        ListRange.ItemsList = numList;        ListRange.Index = Random.Range(1, 11);    }}
Creating custom control in Unity3D that has same UI but different behavior
c#;object oriented;design patterns;unity3d
Use Strategy pattern:Example:public interface RangeControlLogic {    void ChangeValue(int direction);    void UpdateValue();    void OnValueChanged();}public class NoneListRangControl : RangeControlLogic {    public float Stepping = 5;    float m_fMinRange = 10;    float m_fMaxRange = 1000;    float m_fValue;    public float Value    {        get { return m_fValue; }        set        {            m_fValue = value;            UpdateValue();        }    }    public float MinRange    {        get { return m_fMinRange; }        set        {            m_fMinRange = value;            UpdateValue();        }    }    public float MaxRange    {        get { return m_fMaxRange; }        set        {            m_fMaxRange = value;            UpdateValue();        }    }    public void ChangeValue (int direction)    {        // your code here...    }    public void UpdateValue ()    {        // your code here...    }    void OnValueChanged ()    {        // your code here..    }}public class ListRangControl : RangeControlLogic {    // simillar to NoneListRangControl but with different implementation} Then you use composition to plug those objects in the RangControl:public class RangeControl : MonoBehaviour {    public RangeControlLogic logic;// this will be either NoneListRangControl or ListRangControl    public void ChangeValue(int direction)    {        logic.ChangeValue(direction);    }    public void UpdateValue()    {        logic.UpdateValue();    }}