You are doing validation in Apex wrong!

Chain of Responsibility is a behavioral design pattern that lets you pass requests along a chain of handlers. Upon receiving a request, each handler decides either to process the request…

Use Chain of Responsibility design pattern, but what is that?

Chain of Responsibility is a behavioral design pattern that lets you pass requests along a chain of handlers. Upon receiving a request, each handler decides either to process the request or to pass it to the next handler in the chain.

First create Validator abstract class:

apex
public abstract class Validator {
    protected Validator next;

    public virtual Validator setNext(List<String> validations) {
        if (!validations.isEmpty()) {
            next = (Validator) Type.forName(validations.remove(0)).newInstance();
            next.setNext(validations);
        }

        return this;
    }

    public abstract Boolean isValid(Account record);
}

And then extend it with your custom isValid, validation method:

apex
public class AccountIndustryValidator extends Validator {
    private static final List<String> SUPPORTED_INDUSTRIES = new List<String>{
        'Electronics', 'Engineering'
    };

    public override Boolean isValid(Account account) {
        return SUPPORTED_INDUSTRIES.contains(account?.Industry) &&
            (next == null ? true : next.isValid(account));
    }
}

Finally, we can use new Validators, to check if the Account we got is a valid one:

apex
public with sharing class AccountController {
    public static Account createAccount(Account account) {
        Validator validator = new AccountIndustryValidator()
            .setNext(new List<String>{ 'AccountTypeValidator' });

        if (validator.isValid(account)) {
            insert account;
        }

        return account;
    }
}

We create the first Validator manually, then all the logic is handled recursively thanks to implementation in an abstract class. In this implementation we are leveraging Dynamic Apex, it gives a lot of flexibility, you can change implementation to use, for example, Custom Metadata!

Text and code were extracted from the original slide. Plain-text version of the whole catalog