You can start by separating business logic and UI CalculatorState and CalculatorLogic is your model/BL and it can be made shareable. Any calculation can take your model and modify it with a result or with an error message (divide by zero etc). It represents the entire I/O of your business logic (calculation on a calculator), you could expand it to support new features, such as history, with minimum refactoring of other code. CalculatorWindow/xaml is your UI, this is the visible part of your code CalculatorVM is the glue between UI and model. // model class public class CalculatorState : INotifyPropertyChanged /*IMPLEMENT, ON ALL PROPERTIES */ { public bool IsError{get;set;} public string ErrorMessage{get;set;} // Value is what's on the calculator screen under normal conditions public double Value {get;set;} // the calculator's memory private double? mem; public double Mem { get { return mem.GetValueOrDefault(Value); } set { mem = value; } } } // business logic public static class CalculatorLogic{ public static readonly Action<CalculatorState, double?> Add = (state,prm)=>state.Value = state.Mem + state.Value; public static readonly Action<CalculatorState, double?> Sub = (state,prm)=>state.Value = state.Mem - state.Value; } // VM component public class CalculatorCommand: ICommand<double?>{ public CalculatorState State {get;set;} public readonly Action<CalculatorState, double?> Calculate; public readonly bool IsTwoOpCommand; public CalculatorCommand(Action<CalculatorState, double?> calculate, CalculatorState state = null, bool isTwoOpCommand = true){ Calculate = calculate; State = state; IsTwoOpCommand = isTwoOpCommand; } public void Execute(double? prm){ if (State!=null){ if (Calculate!=null){ // for two-op commands without a Mem put the Value in Mem if (!IsTwoOpCommand || State.Mem.HasValue) Calculate(State); else State.Mem = State.Value; } else { State.IsError = true; State.ErrorMessage = "Null function"; } } else // throw if you wish Debug.WriteLine("Unexpected empty state"); } } // View-Model, links your UI to the model public CalculatorVM : INotifyPropertyChanged { public readonly CalculatorState State; public readonly ICommand AddCommand; public readonly ICommand SubCommand; .... public readonly ICommand NumberCommand; public CalculatorVM(CalculatorState state){ State = state; NumberCommand = new CalculatorCommand(c,p=>c.Value = c.Value*10 + p, State, false); SubCommand = new CalculatorCommand(CalculatorLogic.Sub State); AddCommand = new CalculatorCommand(CalculatorLogic.Add, State); } } // View (UI). If you did the rest of the work your UI class should be mostly empty, // most of the setup would be done in the declarative part (XAML) via bindings // this allows you to reuse your entire business logic, unit test included // when you decide to switch platforms (desktop, mobile, server) public CalculatorWindow: Window{ public CalculatorWindow(){ BindingContext = new CalculatorVM(new CalculatorState()); InitializeComponent(); } } CalculatorWindow.xaml: <CalculatorWindow....> ... <TextBlock Text="{Binding State.Value}"/> ... <TextBlock Text="{Binding State.ErrorMessage}" Visibility="{Binding State.IsError, Converter={...bool-to-visible-converter}}"/> ... <Button Command="{Binding NumberCommand}" CommandParameter="0">0</Button> ... <Button Command="{Binding AddCommand}">+</Button> </CalculatorWindow>