/***********************************************************************************************************
 * Name         : FieldVisibilityDependency
 * Purpose      : Clear dependent fields when a controlling field’s value changes on Sobjects.
 **********************************************************************************************************/
public with sharing class FieldVisibilityDependency {
    public String fieldName;
    public Object controllingValue;
    public List<String> dependentFields;

    public FieldVisibilityDependency(String fieldName, Object controllingValue, List<String> dependentFields) {
        this.fieldName = fieldName;
        this.controllingValue = controllingValue;
        this.dependentFields = dependentFields;
    }

    /** compares old vs new and, if the controlling field changes
     *  away from the specified value, clears (sets to null) the configured dependent fields.
     *  @param newList records being updated
     *  @param oldMap prior versions of those records
     *  @param dependenciesList rules 
     */
    public static void handleFieldVisibilityDependencies(
        List<SObject> newList,
        Map<Id, SObject> oldMap,
        List<FieldVisibilityDependency> dependenciesList
    ) {
        for (SObject sobj : newList) {
            SObject oldRec = oldMap.get((Id) sobj.get('Id'));

            for (FieldVisibilityDependency dep : dependenciesList) {
                Object oldVal = oldRec.get(dep.fieldName);
                Object newVal = sobj.get(dep.fieldName);

                if (oldVal == dep.controllingValue && newVal != dep.controllingValue) {
                    for (String dependentField : dep.dependentFields) {
                        sobj.put(dependentField, null);
                    }
                }
            }
        }
    }
}