The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
BNL: The Problem - Update

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Jay Fields

Posts: 765
Nickname: jayfields
Registered: Sep, 2006

Jay Fields is a software developer for ThoughtWorks
BNL: The Problem - Update Posted: Oct 7, 2006 3:28 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Jay Fields.
Original Post: BNL: The Problem - Update
Feed Title: Jay Fields Thoughts
Feed URL: http://blog.jayfields.com/rss.xml
Feed Description: Thoughts on Software Development
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Jay Fields
Latest Posts From Jay Fields Thoughts

Advertisement
The concept behind this 'chapter' is basically the same as the last time I put it on my blog; however, the example is largely new. As always, feedback welcome.

Business Natural Languages: Introduction
Business Natural Languages: The Problem

The Problem
To demonstrate the value in implementing a Business Natural Language we will start with an existing ruby application and then introduce a simple Business Natural Language. This approach should provide a good example of how to include a Business Natural Language in an application.

For the sample application imagine you've been contracted to replace a payroll calculation system for a consulting company. The consulting company chose to custom develop the software for calculating payroll because of the varying compensation packages. They have given you profiles of 2 employees and the business rules required to generate compensation.

Profiles:
John Jones
compensate $2500 for each deal closed in the past 30 days
compensate $500 for each active deal that closed more than 365 days ago
compensate 5 percent of gross profits if gross profits are greater than $1,000,000
compensate 3 percent of gross profits if gross profits are greater than $2,000,000
compensate 1 percent of gross profits if gross profits are greater than $3,000,000

Jackie Johnson
compensate $3000 for each deal closed in the past 30 days
compensate $800 for each active deal that closed more than 365 days ago
compensate 5 percent of gross profits if gross profits are greater than $1,000,000
compensate 5 percent of gross profits if gross profits are greater than $2,000,000

The application need only be run monthly; therefore, manual execution of the application is acceptable. The existing application is executed at the command line and the results are displayed to the screen. The payroll department records the application results in another system that is outside of the scope of your work. A preprocess is run to put monthly sales information in a known location in an agreed upon format, this is also outside the scope of your work. The only input files we will need for our sample application are jjones.yml and jjohnson.yml.

File: jjones.yml
employee: jjones
deals_this_month: 7
year_old_deals: 2
gross_profit: 1400000
File: jjohnson.yml
employee: jjohnson
deals_this_month: 12
year_old_deals: 1
gross_profit: 2200000
The SalesInfo class currently reads the sales data and exposes it via class method calls that are handled by method_missing.

File: sales_info.rb
require 'yaml'

class SalesInfo

@employee_sales_info = Dir['*.yml'].collect do |filename|
YAML::load(File.open(filename))
end

def self.method_missing(sym, *args)
hash = @employee_sales_info.find { |hash| hash.value?(sym.to_s) }
super if hash.nil?
EmployeeInfo.new(hash)
end

class EmployeeInfo
attr_reader :employee, :deals_this_month, :year_old_deals, :gross_profit
def initialize(hash)
hash.each_pair do |key, value|
instance_variable_set :"@#{key}", value
end
end
end

end
The ruby file that executes the current payroll process is very straightforward:

File: process_payroll.rb
require 'jjones'
require 'jjohnson'

puts "John Jones compensation: #{JJones.calculate}"
puts "Jackie Johnson compensation: #{JJohnson.calculate}"
Each employee ruby file is also fairly straightforward. They contain the logic to calculate compensation, expressed as ruby.

File: jjones.rb
require 'sales_info'

class JJones
def self.calculate
total = SalesInfo.jjones.deals_this_month * 2500
total += SalesInfo.jjones.year_old_deals * 500
profit = SalesInfo.jjones.gross_profit
total += profit * 0.05 if profit > 1000000
total += profit * 0.03 if profit > 2000000
total += profit * 0.01 if profit > 3000000
total
end
end
File: jjohnson.rb
require 'sales_info'

class JJohnson
def self.calculate
total = SalesInfo.jjohnson.deals_this_month * 3000
total += SalesInfo.jjohnson.year_old_deals * 800
profit = SalesInfo.jjohnson.gross_profit
total += profit * 0.05 if profit > 1000000
total += profit * 0.05 if profit > 2000000
total
end
end
The existing application produces the following output.

John Jones compensation: 88500.0
Jackie Johnson compensation: 256800.0

The code produces accurate results; however, the code has limited ability to easily be extended for new employees. Additionally, employees are required to re-negotiate their compensation structure every year. Following a compensation change a programmer must be involved to change the employees logic. The current process is clearly sub-optimal

Read: BNL: The Problem - Update

Topic: Want to move to Portland? Previous Topic   Next Topic Topic: Want to move to Portland?

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use