'Enforce Validation at the Model Level

I have a model class and find myself enforcing validation rules in multiple places: when initially creating the object via a form, when allowing the object to be edited in another form, when manipulating the object within a function, etc.

In the end, the only real "validation rule" is me knowing in my head it needs to be done. If I forget to enforce it somewhere, future access to that object may cause a runtime error elsewhere.

I'm wondering how can I get as close as possible to the base model to enforce a validation rule (even if I redundantly enforce again later).

The two solutions I can think of are using an assert and/or throwing. Do other or better solutions exist? Can I get an error before runtime?

(Note: I'm assuming one approach will be to eventually write tests, but I haven't learned this skillset yet.)

Example:

Rule - "If the object's ExampleEnum is single, the list of integers must contain one but no more than one integer. If the object's ExampleEnum is multiple, the list of integers must contain at least one integer."

enum ExampleEnum { single, multiple }

class Foo {
  Foo({
    this.fooList = [1,2,3];
    this.fooEnum = exampleEnum.multiple;
  })

//BRAINSTORMED SOLUTION: 
 : assert (fooEnum == ExampleEnum.multiple && fooList.length != 1) || (fooEnum == ExampleEnum.single && fooList.isEmpty, 'NO!',);

  final List<int> fooList;
  final ExampleEnum fooEnum;

Foo copyWith({
  List<int>? fooList,
  ExampleEnum? fooEnum,
}) {

//BRAINSTORMED SOLUTION:
  if (fooEnum == ExampleEnum.multiple && fooList.length != 1) || (fooEnum == ExampleEnum.single && fooList.isEmpty) {
  throw 'NO!';
}
 return Foo(
  fooList: fooList ?? this.fooList,
  fooEnum: fooEnum ?? this.fooEnum,
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source