Tener una API de excepción robusta y bien diseñada que sea consistente es muy apropiado. Usar esto para hacer cumplir las reglas comerciales también puede ser apropiado. De hecho, en mi experiencia, cuanto más complicada es la regla de negocios, más probable es que termine siendo manejada de esta manera. A menudo es tan fácil, si no más fácil, escribir un sistema donde se esperan excepciones que escribir una lógica de ramificación autorizada.
Esto quiere decir que las reglas simples que se pueden describir en una sola oración generalmente deben implementarse de manera preventiva o autorizada, según cuál sea. Sin embargo, si tiene una regla que es multidimensional y requiere más de tres o cuatro factores (especialmente si la selección de estos factores se basa en uno o más de los otros factores), entonces la codificación de excepción puede ser más fácil de mantener. A menudo, en estos casos, la ruta lógica tendrá muchas excepciones precursoras que deben lanzarse (verifica por qué no se puede realizar la acción) y luego (o viceversa) hay una caída en la seguridad (para verificar que la acción esté autorizada ), a veces habrá alguna lógica de acumulación autorizada que debe verificarse (disponibilidad descendiente / ancestro, estados precursores en los que se deben colocar los objetos, etc.
Un beneficio que se deriva de este tipo de lanzamiento de excepciones es que le permite separar y reutilizar las excepciones precursoras en múltiples áreas de su proyecto. (Esta es la esencia de la Programación Orientada a Aspectos). Al hacer esto, está encapsulando un aspecto particular de sus reglas comerciales generales en un componente autónomo y mantenible. En general, estos componentes corresponderán 1-1 con los mensajes de error lanzados. (Aunque a veces tendrá un componente que arroja varias excepciones diferentes, casi nunca debería tener la misma excepción lanzada desde múltiples componentes).
En mi opinión, es más difícil diseñar sistemas que se basen en excepciones y el tiempo de desarrollo inicial es más largo ya que tiene que construir el proceso de excepción en todos los N niveles. Sin embargo, estos sistemas generalmente terminan siendo mucho más estables. Si bien nunca es posible diseñar un sistema que 'no fallará', el beneficio del diseño basado en excepciones es que siempre está anticipando la falla. Para la mayoría de las personas, el proceso puede ser contra intuitivo. Es como pedir indicaciones y que alguien te diga todas las calles que no debes encender.