我有一个员工班,我可以存储员工详细信息,如年龄,DOB和赚取的积分。
class Employee
attr_accessor :id, :dob, :points
def initialize
@id = id
@dob = dob
@points = points
end
def tranfer_points
# Access both employee objects and add points to one and remove points from other
end
end
emp_one = Employee.new(1,"2 Jan 1990",400)
emp_two = Employee.new(2,"12 Jan 1986",700)
emp_two.transfer()
我想知道维护所有已创建对象的最佳做法是什么,以便我可以将点从一个员工转移到另一个员工。
我应该在这里使用类变量,这是一个很好的解决方案,它是一个标准做法吗?
如下所示
class Employee
@@all_employee = Hash.new
attr_accessor :id, :dob, :points
def initialize
@id = id
@dob = dob
@points = points
add_all_employee
end
def add_all_employee
@@all_employee[id] = self
end
def tranfer_points(i,points)
b = @@all_employee[i]
self.balance -= points
b.points += points
end
end
这里的任何帮助将不胜感激。感谢。
答案 0 :(得分:1)
以下是如何执行此操作的示例。
使用数据库:
class Employee
def tranfer_points_to(recipient, num_points)
Employee.transaction do
self.update!(points: self.points - num_points)
recipient.update!(points: recipient.points + num_points)
end
end
end
使用Rails Transaction是一种很好的方法,可以确保您不会意外更新一个而不是另一个,以防此块中出现异常。
没有数据库:
class Employee
def tranfer_points_to(recipient, num_points)
self.points -= num_points
recipient.points += num_points
end
end
更新: 回答你的意见:
如果您考虑使用数据库,那么它就不用了,只需保存模型即可。 没有数据库,使用某些父类来保持"保持"员工实例。一个例子:
class Company
attr_reader :employees
def initialize
@employees = []
end
def add_employee(id, dob, points)
employees.push(Employee.new(id, dob, points))
end
def tranfer_points(from_employee_id, to_employee_id, num_points)
find_employee_by_id(from_employee_id).points -= num_points
find_employee_by_id(to_employee_id).points += num_points
end
def find_employee_by_id(id)
employees.find { |e| e.id == id }
end
end
company = Company.new
company.add_employee(1, "2 Jan 1990", 400)
company.add_employee(2, "2 Jan 1991", 400)
company.transfer_points(1, 2, 200)
company.find_employee_by_id(1).points => 200
company.find_employee_by_id(2).points => 600
答案 1 :(得分:0)
以下是一个例子:
require 'singleton'
require 'forwardable'
require 'thread'
class EmployeeStore
include Singleton
class << self
extend Forwardable
def_delegator :instance, :employees, :employees
def_delegator :instance, :find, :find
def_delegator :instance, :add, :add
def_delegator :instance, :transfer_points, :transfer_points
def_delegator :instance, :remove, :remove
end
def employees
@employees.dup
end
def find(id)
@employees[id].dup
end
def add(employee)
@employees[employee.id] = employee
end
def remove(employee)
case employee
when Employee
@employees.delete(employee.id)
when Fixnum
@employees.delete(employee)
else
raise "Don't know how to delete #{employee}"
end
end
def transfer_points(from, to, points)
# EmployeeStore is the only way to modify @employees
real_from, real_to = find(from.id), find(to.id)
# synchronize for thread-safe
@mutex.synchronize do
f_points, t_points = from.points, to.points
begin
real_from.instance_variable_set(:@points, f_points - points)
real_to.instance_variable_set(:@points, t_points + points)
# do something else
rescue
real_from.instance_variable_set(:@points, f_points)
real_to.instance_variable_set(:@points, t_points)
ensure
from.instance_variable_set(:@points, real_from.points)
to.instance_variable_set(:@points, real_to.points)
end
end
end
private
def initialize
@employees = {}
@mutex = Mutex.new
super
end
end
class Employee
attr_reader :id, :dob, :points
def initialize(id, dob, points)
@id, @dob, @points = id, dob, points
EmployeeStore.add(self)
end
def transfer_points_to(employee, points)
EmployeeStore.transfer_points(self, employee, points)
end
end
Employee.new(1, "2 Jan 1990", 400)
Employee.new(2, "12 Jan 1986", 700)
emp_one = EmployeeStore.find(1)
emp_two = EmployeeStore.find(2)
1.upto(10).map do
Thread.new do
emp_one.transfer_points_to(emp_two, 30)
end
end.map(&:join)
p emp_one.points # => 100
p emp_two.points # => 1000
类变量不是线程安全的