Joe Joe - 6 months ago 9
Ruby Question

Two Ruby Classes Depending on Each Other

I'm currently having a little trouble managing my dependencies whilst trying to maintain Single Responsibility and OOD.

I have a master class call Menu:

class Menu

def initialize(dishes:, prices:, menuFormatter:)
@dishes = dishes
@prices = prices
@menuFormatter = menuFormatter
end

def avaliable_dishes
dishes.dishes_list
end

def dish_prices
prices.prices_list
end

def formatted_menu
menuFormatter.formatted_menu
end

private

attr_reader :dishes, :prices, :menuFormatter
end


Now, the way I see it is that the Menu class pulls together all of the different parts of the menu, and supplies it to the hypothetical customer. The dishes are handled, updated, removed in their own class (Dishes), the prices are done in the same way (Prices) and then there is a separate class MenuFormatter who's responsibility is to take the contents of the Menu and turn it into a nicely arranged menu. Lines 17 to 19 are where my MenuFormatter class is called into action but my problem arises within that class:

class MenuFormatter

def avaliable_dishes
menu.avaliable_dishes
end

def dish_prices
menu.dish_prices
end

def format_menu
#Loop through dishes and prices and arrange them.
end
end


The error i'm not faced with is that the MenuFormatter doesn't know what menu is because i've not defined it within the class. I'm unsure how to make my menu variable point to the instance of Menu so that it can have access to the dishes and prices.

I'd hoped not to give MenuFormatter access to Dishes or Prices as I feel that could lead to further coupling than necessary within my code.

Answer

How about passing the instance of menu itself as an argument to the format_menu method:

def formatted_menu
  menuFormatter.formatted_menu(self)
end

Here, in the definition of an instance method of the Menu class, self refers to the instance of menu on which the formatted_menu method is called.

And then in MenuFormatter:

def formatted_menu(menu)
  # menu.dishes... 
  # menu.prices....
end