I've written this trigger to Update Total Numbers of Contact in related Account Custom Field... All Code is written in Apex Trigger However, I've been told that it's best practice to split this into an Apex Class with a simple Trigger calling the Class
Can someone please guide me How do I add apex Class with trigger on below code? I know it is too much to ask but it will clear my concept related apex:Class and in Future i'll be able to create Neat and Clean Trigger.

```
trigger UpdateContactCountOnAccount on Contact (after insert, after update, after delete)
{
    Set<Id> accountsIds = new Set<Id>();
    List<Account> acc = [SELECT Id,No_of_Contacts__c FROM Account WHERE Id IN:accountsIds];
    List<Contact> con = [SELECT Id FROM contact WHERE AccountId IN :accountsIds];
    if(Trigger.isInsert)
    {
        for(Contact contactTriggerList : Trigger.New)
        {
            accountsIds.add(contactTriggerList.AccountId);
        }
        for(Account accountList : acc)
        {
            accountList.No_of_Contacts__c=con.size();
        }
        Update acc;
    }
    if(Trigger.isDelete)
    {
        for(Contact contactTriggerList : Trigger.old)
        {
            accountsIds.add(contactTriggerList.AccountId);
        }
        for(Account accountList : acc)
        {
            accountList.No_of_Contacts__c=con.size();
        }
        Update acc;
    }
    if(Trigger.isUpdate)
    {
        Set<Id> oldAccountIds = new Set<Id>();
        for(Contact contactTriggerList : Trigger.new)
        {  
            if(contactTriggerList.AccountId != Trigger.oldMap.get(contactTriggerList.id).AccountId)
            {
                accountsIds.add(contactTriggerList.AccountId);
            }
            oldAccountIds.add(Trigger.oldMap.get(contactTriggerList.id).AccountId);    
        }  
        if(!accountsIds.isEmpty())
        {  
            for(Account accountList : acc)
            {
                accountList.No_of_Contacts__c=con.size();
            }
            Update acc;

            //for Old Accounts and Contacts
            List<Account> OldaccountList = [SELECT Id,No_of_Contacts__c FROM Account WHERE Id IN:oldAccountIds];
            List<Contact> OldContactList = [SELECT Id FROM contact WHERE AccountId IN :oldAccountIds];

            for(Account accountList : OldaccountList)
            {
                accountList.No_of_Contacts__c=OldContactList.size();
            }
            Update OldaccountList;
        }
    }
}

```

Thanks,
Dave