railsconf 2010: from 1 to 30 - how to refactor one monolithic application into an application...
DESCRIPTION
As your business grows bigger, you just can’t stop adding new models/controllers to your original rails application – resulting in a messy, unmaintainable and difficult to deploy monolithic application. Its time to refactor. This talk will share our experience, results and best practices in splitting a single rails “application-system” into 30 independently maintainable yet interconnected applications. After two and a half years of development (starting in pre-Rails 1.0 days!), our live-trainer English learning system now supported multiple roles (learner/trainer/trainer supervisor/sales/materials creation/support/etc) and an exhaustive list of features to support our complex business processes. We set ourselves a year-long goal of splitting this monolithic system into small cooperating applications that could be developed independently by individual developers. At the same time, we could not lose the usability cohesiveness and data-interdependence that defined the power of our system. Through numerous iterations, many mistakes and a bit of pure-luck we developed an optimized process for the refactor and best practices for making 30 independent rails apps behave as one. The results: lower development time, greater stability and scalability and much higher developer happiness. We’ll talk about specific code, measurements, pitfalls, plugins, process and best practices to answer questions such as: How to know where to split single applications into many. How to measure the result. How the applications should interact with each other. How to reduce administration and DRY configuration applications. How to share data among applications. How to DRY for common logic. How to make a consistent user experience. How to interact with non-Ruby technology; in our case Erlang, FreeSWITCH (VoIP) and FlexTRANSCRIPT
![Page 1: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/1.jpg)
From 1 To 30How To Disassemble
One Monster App Into An Ecosystem Of 30
Jonathan Palley, CTO/COO
Guo Lei, Chief Architect
© 2010 Idapted, Ltd.
![Page 2: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/2.jpg)
An
Experience
![Page 3: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/3.jpg)
A Tale of Two Buildings
![Page 4: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/4.jpg)
2009 ShanghaiLotus Riverside Community
1909 BeijingForbidden City
![Page 5: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/5.jpg)
1
30
![Page 6: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/6.jpg)
What is one?
![Page 7: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/7.jpg)
The entire web application/system/platform
runs as one single rails application
(We are talking about really large systems. Multiple different types of clients/functions)
![Page 8: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/8.jpg)
Problems
Hard to test/extend/scale
Confused new staff
![Page 9: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/9.jpg)
What is 30?
![Page 10: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/10.jpg)
A ecosystem of applications
![Page 11: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/11.jpg)
Independent
![Page 12: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/12.jpg)
Linked and Seamless
![Page 13: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/13.jpg)
Basic features of each app• Separate database• Runs independently (complete story) • Lightweight (single developer)• Tight internal cohesion and loose external coupling
Advantages• Independent Development Cycle• Developer autonomy• Technology (im)maturity safety
APPEAL TO DEVELOPER LAZINESS
![Page 14: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/14.jpg)
What’s the mystery of the forbidden city?
![Page 15: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/15.jpg)
Consistent UI
• Shared CSS/JS/Styleguide• Common Helpers in Shared Gem• Safely try new things
![Page 16: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/16.jpg)
All applications use the same base CSS/JS
Keep all the application the same style
<%= idp_include_js_css %># =><script src ="/assets/javascripts/frame.js" type="text/javascript"></script><link href="/assets/stylesheets/frame.css" media="screen" rel="stylesheet"
type="text/css" />
interface
![Page 17: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/17.jpg)
CSS Frameworkinterface
![Page 18: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/18.jpg)
Abstract Common Helpers to Gem
Search function for models
interface
![Page 19: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/19.jpg)
Common Helpers: Combo search (cont)
View:<%= search_form_for(HistoryRecord, :interaction_id, :released,[:rating, {:collection=>assess_ratings}],[:mark_spot_num,{:range=>true}], [:created_at, {:ampm=>true}]) %>
Controller:@history_records = HistoryRecord.combo_search(params)
interface
![Page 20: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/20.jpg)
Common Helpers: List table
well formattedwith pagination
sortablecustomizable
interface
![Page 21: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/21.jpg)
Common Helpers: List table (cont)<%= idp_table_for(@history_records,:sortable=>true,:customize => "history_records") do |item, col| col.add :id, link_to(item.id, admin_history_record_path(item)),:order=>:id col.build :duration, :waiting_time, :review_time col.add :scenario, item.scenario_title, :order => :scenario_title col.add :mark_spot_num end%>
interface
![Page 22: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/22.jpg)
Development Lifecycle
interface
1. Implement new View code/plugin in a second application
2. Abstract into plugin using existing “idp” helpers
3. Put it into main view gem
![Page 23: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/23.jpg)
interface data
![Page 24: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/24.jpg)
How do applications share data?(remember: each app has its own data)
data
-“Read Only” Database Connections- Services- AJAX Loaded View Segments
![Page 25: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/25.jpg)
Business example
user
course
purchase
learning process
data
![Page 26: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/26.jpg)
Purchase App
Requirement: List course packages for user to select to purchase
The course package data is stored in the “course” application
but
data
![Page 27: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/27.jpg)
Solution
readonly db connection
data
course
![Page 28: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/28.jpg)
Code
Model:class CoursePackage < ActiveRecord::Base acts_as_readonly :courseend
View:<ul><% CoursePackage.all.each do |package| %> <li><%= package.title %> <%= package.price %></li><% end %></ul>
data
![Page 29: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/29.jpg)
Why doesn’t this break the rule of loose coupling?
data
![Page 30: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/30.jpg)
acts_as_readonly in Depth
def acts_as_readonly(name, options = {})config = CoreService.app(name).databaseestablish_connection config[Rails.env]set_table_name(self.connection.current_database + (options[:table_name]||table_name).to_s)
end
data
![Page 31: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/31.jpg)
acts_as_readonly in Depth
def acts_as_readonly(name, options = {})
config = CoreService.app(name).databaseestablish_connection config[Rails.env]set_table_name(self.connection.current_database + (options[:table_name]||table_name).to_s)
end
data
![Page 32: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/32.jpg)
Core service
class CoreService < ActiveResource::Base self.site = :userdef self.app(app_name)
CoreService.find(app_name)end
end
data
![Page 33: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/33.jpg)
Centralized configurationdata
How does Core know all the configurations?
![Page 34: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/34.jpg)
Each app posts its configuration to core when it is started
data
![Page 35: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/35.jpg)
data
config/site_config.ymlapp: courseapi: course_list: package/courses
config/initializers/idp_initializer.rb
CoreService.reset_config
![Page 36: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/36.jpg)
data
core_service.rb in idp_lib
APP_CONFIG = YAML.load(Rails.root.join(“config/site_config.yml”))
def reset_config self.post(:reset_config, :app => { :name => APP_CONFIG["app"], :settings => APP_CONFIG, :database => YAML.load_file(
Rails.root.join("config/database.yml"))})end
![Page 37: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/37.jpg)
data
![Page 38: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/38.jpg)
Again, implemented in gem
data
config/environment.rb
config.gem ‘idp_helpers’config.gem ‘idp_lib’
![Page 39: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/39.jpg)
data
gems
![Page 40: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/40.jpg)
• Web services for “write” interactions
class CoursePackageService < ActiveSupport::Base self.site = :courseend
data
![Page 41: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/41.jpg)
example
Roadmap needs to be generated after learner pays.
data
![Page 42: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/42.jpg)
codesCourse: app/controllers/roadmap_services_controller.rb
def createRoadmap.generate(params[:user_id], params[:course_id])
end
Purchase: app/models/roadmap_service.rb
class RoadmapService < ActiveSupport::Base self.site = :courseendPurchase: app/models/order.rb
def activate_roadmap RoadmapService.create(self.user_id, self.course_id)end
data
![Page 43: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/43.jpg)
AJAX Loaded Composite Viewdata
<div><%= ajax_load(url_of(:course, :course_list)) %></div>
Fetched from different
applications
Ecosystem url_for
![Page 44: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/44.jpg)
interface data user
![Page 45: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/45.jpg)
Features of User Service
• Registration/login• Profile management• Role Based Access Control
user
![Page 46: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/46.jpg)
Access Control
Each Controller is one Node
user
* Posted to user service when app starts
![Page 47: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/47.jpg)
Access Control
before_filter :check_access_right
def check_access_right unless xml_request? or inner_request? access_denied unless has_page_right?(params[:controller]) endend
user
* Design your apps so access control can be by controller!
![Page 48: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/48.jpg)
How to share?
user
![Page 49: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/49.jpg)
Step 1: User Authuser
![Page 50: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/50.jpg)
Step 1: User Auth
config/initializers/idp_initializer.rb
ActionController::Base.session_store = :active_record_storeActiveRecord::SessionStore::Session.acts_as_remote :user,
:readonly => false
user
![Page 51: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/51.jpg)
Step 2: Access ControlTell core its controllers structure
CoreService. reset_rights
def self.reset_rights data = load_controller_structure
self.post(:reset_rights, :data => data)end
user
![Page 52: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/52.jpg)
Step 2: Access Control
before_filter :check_access_right
def check_access_right unless xml_request? or inner_request? access_denied unless has_page_right?(params[:controller]) endend
user
![Page 53: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/53.jpg)
Step 2: Access Control
has_page_right?
Readonly db conn again
user
![Page 54: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/54.jpg)
Step 2: Access Control
def has_page_right?(page) roles = current_user.roles
roles_of_page = IdpRoleRight.all(:conditions => ["path = ?", page]).map(&:role_id)
(roles - (roles - roles_of_page)).size > 0end
class IdpRoleRight < ActiveRecord::Base acts_as_readonly :user, :table_name => "role_rights"end
user
![Page 55: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/55.jpg)
Again, gems!user
config/environment.rb
config.gem ‘idp_helpers’config.gem ‘idp_lib’config.gem ‘idp_core’
![Page 56: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/56.jpg)
interface servicedata user
![Page 57: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/57.jpg)
Support applications
• File• Mail• Comet service
service
![Page 58: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/58.jpg)
Fileclass Article < ActiveRecord::Base has_filesend
@article.files.first.url
Upload File in Background to
FileService
Store with app_name,
model_name, model_id
Use readonly magic to easily
display
Idp_file_form
Specify Class that Has Files
![Page 59: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/59.jpg)
Cometservice
class ChatRoom < ActiveRecord::Base acts_as_realtime end
<%= realtime_for(@chat_room, current_user.login) %>
<%= realtime_data(dom_id, :add, :top) %>
@chat_room.realtime_channel.broadcast(“hi world", current_user.login)
![Page 61: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/61.jpg)
Host all in one domain
Load each rails app into a subdir, we use Unicorn
unicorn_rails --path /user unicorn_rails --path /studycenter unicorn_rails --path /scenario
![Page 62: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/62.jpg)
Host all in one domain
use Nginx as a reverse proxy
location /user { proxy_pass http://rails_app_user; }
location /studycenter { proxy_pass http://rails_app_studycenter; }
![Page 63: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/63.jpg)
Host all in one domain
All you see is a uniform URL
www.eqenglish.com/user www.eqenglish.com/studycenter www.eqenglish.com/scenario
![Page 64: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/64.jpg)
![Page 65: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/65.jpg)
Pair-deploy
![Page 66: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/66.jpg)
How to split one into many?
![Page 67: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/67.jpg)
By Story
Each App is one group of similar features.
By DataEach App writes to the same data
![Page 68: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/68.jpg)
Example
• User Management• Course package• Purchase• Learning process• …
![Page 69: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/69.jpg)
Iteration
![Page 70: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/70.jpg)
Be adventurous at the beginning.Split one into as many as you think
is sensitive
![Page 71: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/71.jpg)
Then you may find
• Some applications interact with each other frequently.
• Lots of messy and low efficiency code to deal with interacting.
![Page 72: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/72.jpg)
Merge them into one.
![Page 73: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/73.jpg)
Measurement
• Critical and core task of single app should not call services of others.
• One doesn’t need to know much about others’ business to do one task (or develop).
• Independent Stories
![Page 74: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/74.jpg)
Pitfalls
• Applications need to be on the same intranet.
• No “right place” for certain cases.
![Page 75: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/75.jpg)
Results: Higher Productivity
-Faster build to deploy-More developer autonomy-Safer- Scalable-Easier to “jump in”- Greater Happiness
![Page 76: RailsConf 2010: From 1 to 30 - How to refactor one monolithic application into an application ecosystem](https://reader037.vdocuments.net/reader037/viewer/2022110307/555ec974d8b42af67f8b510b/html5/thumbnails/76.jpg)
© 2010 Idapted, Ltd.
Thank you!
Q&Ahttp://www.idapted.comhttp://developer.idapted.comhttp://t.sina.com.cn/[email protected] (@jpalley)[email protected] (@fiyuer)