Evolutionary architecture and emergent design

Source: Internet
Author: User
Tags definition class definition constant numeric ruby on rails

In previous installments, I have begun to introduce the harvesting of domain idiomatic patterns (solutions for urgent business problems) by using domain-specific languages. For this task, DSL work is good because they are concise (with as few noisy syntax as possible) and readable (even by developers), and they stand out from more API-centric code. In the previous issue, I had shown how to use Groovy to build a DSL to take advantage of some of its features. In this section, I'll end the discussion of using a DSL to get idiomatic patterns by showing how to build a more complex DSL in Ruby and using JRuby.

About this series

This series aims to introduce a new perspective on software architecture and design concepts that are often discussed but difficult to understand. With a concrete example, Neal Ford will help you lay a solid foundation for the evolutionary architecture and the agile practices of emergent design. By deferring important architectural and design decisions to the final responsibility, you can prevent unnecessary complexity from reducing the quality of your software project.

Ruby is the most popular language currently used to build an internal DSL. Most of the infrastructure you consider when developing on Ruby is DSL based-ruby on Rails, RSpec, Cucumber, Rake, and many others-because it is subordinate to the host-managed internal DSL. The trendy technology of behavioral-driven Development (BDD) requires a strong DSL base to achieve its popularity. This issue will help you understand why Ruby is so popular among DSL fans.

Open Classes in Ruby

Using an open class to add a new method to a built-in class is a common technique for adding expressiveness to a DSL. In the previous issue, I showed two different syntaxes for open classes in Groovy. In Ruby, you have the same mechanism in addition to using a single syntax. For example, to create a recipe DSL, you need a way to catch the catches. Please consider the DSL fragment in Listing 1:

Listing 1. Target syntax for my Ruby based recipe DSL

recipe = Recipe.new "Spicy bread"
recipe.add 200.grams.of "flour"
recipe.add 1.lb.of "nutmeg"

To make this code executable, I must open the Numeric class to add the gram and LB methods to the number, as shown in Listing 2:

Listing 2. Open Class definition in Ruby

class Numeric
  def gram
   self
  end
  alias_method :grams, :gram

  def pound
   self * 453.59237
  end
  alias_method :pounds, :pound
  alias_method :lb, :pound
  alias_method :lbs, :pound

In Ruby, class names must start with uppercase letters, and they are also rules for Ruby constants, which means that each class name is also a constant. When Ruby "sees" the class definition, it looks at whether it has loaded the class on its classpath. Because the class name is a constant, you can only have a class with a given name. If the class is already loaded, the class definition will reopen the class to allow me to make changes. In Listing 2, I reopened the Numeric class (which handles fixed and floating-point numbers) to add the gram and pound methods. Unlike Groovy, Ruby does not have rules that must be invoked with empty parentheses for methods that receive no parameters, which means Ruby does not have to distinguish between properties and methods.

Ruby also includes another handy DSL mechanism: the Alias_method class approach. If you want to improve your DSL fluency as much as possible, it is recommended that you deal with cases of a similar diversity. (If you want to see the effort to make this happen, look at the multiplex code for dealing with the plural model class name in Ruby on Rails.) When I clearly add more than one gram, I don't want to syntactically form a clumsy sentence like Recipe.add 2.gram.of ("flour") in my DSL. The alias_method mechanism in Ruby makes it easier to create alternate names for methods to enhance readability. To do this, listing 2 adds a multiple approach to gram and adds alternate abbreviations and a plurality of versions for pound.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.