Posted over 3 years ago. Visible to the public. Linked content.
Defensive Programming via Validating Decorators
Please read the original blog post by Yegor Bugayenko. He uses Java in the examples so I have tried to create possible Ruby version.
Copy# bad version class Report def export(filename) raise ArgumentError, 'No file name provided' unless filename raise ArgumentError, 'File already exists' if File.exist?(filename) # export a report to the file end end
First we create a module to resemble Java interfaces more or less.
Copymodule Reportable def export(filename) raise NotImplementedError end end
Than add class that actually generates a requested report.
Copyclass DefaultReport include Reportable def export(filename) # generate a report and save it in the filename end end
Now let's implement couple decorators to validate filename presence and uniqueness.
Copyclass NoNullReport include Reportable def initialize(report) @origin = report end def export(filename) raise ArgumentError, 'No file name provided' unless filename origin.export(filename) end private attr_accessor origin end class NoOverwriteReport include Reportable def initialize(report) @origin = report end def export(filename) raise ArgumentError, 'File already exists' if File.exist?(filename) origin.export(filename) end private attr_accessor origin end
Finally the usage.
Copyreport = NoNullReport.new NoOverwriteReport.new DefaultReport.new report.export 'myfile.csv'