超級全能危樓改造王
增建、改建、打掉重建你的軟體架構?
Spirit Tu
Senior Program Analyst, GSS
White Day, 2013
Warning
• Sorry, this is an English slide
• I am a good man
– Don’t ask where the (bad) examples come from
• The patterns and methods mentioned today can be found in the following books
2
DP POSA RF PEAA
Taking the Teddy’s courses is one of the fastest ways
I want to believe
3
Alien?
Do you believe evolutional software
architecture?
About me
• Before the doom, I received the Ph. D. degree
4
The experiences
• Recently, I updated my profile on Link-in
– Six-year teaching assist (Saw many bad examples)
– A distributed wireless communication protocol (WiMAX) simulator and emulator (Project Manager, Aug 2006 – July 2009)
– An embedded DVB-H transport stream decoder (Scrum Master, Aug 2009 – July 2011)
– A configurable conference management system & A distributed load testing framework (Consultant and test planner, Aug 2011 – July 2012)
– An Android game framework for teaching OOP Lab (Major refactoring for release, Jan 2012 – Apr 2012)
5
Snapshots of the WiMAX emulator
6
“Big design up front” won this time
• Recall the first year of the first project
– Chaos, spaghetti, etc.
• Starting of the second year
– Requirement change: 802.16d 802.16e
– Throw away vs. refactoring
– I played both the PM and SA roles.
– The architecture design took almost three months.
– However, it did work!!
– In addition, we were happy to add new functions in the third year.
7
The architecture
8
MAC
PHY1
SECU
PHY2
Data Socket
Socket
Application
Driver
Control Socket
Data Socket
Control Socket
Mobile Station
Base Station
Agent
MAC
PHY1
SECU
PHY2
Socket
Application
Driver
Control Socket
Data Socket
CHN
Single Layer Simulation
UI & Console
SYS UI
Control Socket
Agent
Agent
Conf.Plug-in
SPMTPlug-in
Data Socket
Control Socket
Gateway
Agent
Routing TableMIMO
PHYMAC
CHN
2 sheets of A2 paper class diagram, 15 sheets of A4 paper sequence diagrams, and totally over 180k LOC
“Big design up front” won, again
• In the second project
– I was the scrum master of a sub-project, but was compelled to be the SA of the main project
– The architecture design took almost four months
– Well, it did work, again!!
• In our sub-project, all features completed near 2-month before the due day
9
DVB-H訊號源
具DVB-H訊號接受器與
Bluetooth或WiFi之裝置A
(需使用本套件)
具Bluetooth或WiFi之
平板B (需使用本套件)
Signal 1
Signal 2
The things that changed my mindset
• In the following projects
– When I involved, chaos or close to chaos
– “Throw away” is forbidden
– Refactoring adding new features chaos refactoring adding new features chaos refactoring, ...
– Evolutional software architecture also works?
• Especially, after I refactored the Android game framework
10
Starting from the MVC pattern
• I use MVC in a GUI application
• Why do we use MVC?
– Separation of concern
– Focus on the problem domain
– Reusable model, etc.
11
always usually often sometimes rarely never
POSA
MVC implementation is easy?
• Do we implement the MVC correctly?
– Are you kidding?
– In Android, Activity is a model, view, or controller?
12
An Activity is an application component that provides a screen with which users can interact in order to do something, such as dial the phone, take a photo, send an email, or view a map. Each activity is given a window in which to draw its user interface. The window typically fills the screen, but may be smaller than the screen and float on top of other windows.
http://developer.android.com/guide/components/activities.html
How to test an Android App?
• I don’t how to test my Android App quickly!!
– I know the advantages of unit tests, but I wrote all the logics in the activities.
– Using the Android testing and Instrumentation framework is very slow.
13
ATMCore (100% Tested)
ATMTextConsole ATMSwingApp ATMAndroidApp
ATMCore (100% Tested)
ATMCore (100% Tested)
Evolution to MVC
• Extract method and extract class
14
View
View
Controller
View
Controller
Model
View Controller
Model
View
Controller Presentation
Model
RF
An example
15
public class CalculatorModel { public Number LeftOperand { get; }; public Number RightOperand { get; }; public Number Result { get; }; public void InputDigit(Button button, TextBox result) { // Append the value of the button to the right operand // Update the text displayed on the text box } } public class CalculatorView : Form { public CalculatorView(CalculatorModel model) { ... Nine.Click += new EventHandler(DigitPressed); } private void DigitPressed(object sender, EventArgs e) { Model.InputDigit((Button)sender, ResultTextBox); } }
Any problem?
Dependencies between MVC
• Observer and Strategy pattern
– Hollywood Principle: don't call us, we'll call you
16
View
Controller Presentation
Model
Direct
Indirect
Strategy & Observer Observer
Program to abstraction Program to abstraction
Strategy
DP
Client-server architecture
• In the O’Reilly head first series, you often see
– “lots of customers love your program, and your boss wants a better program that has ...”
– The boss wants a cloud-based App
• Client server pattern is a good choice
– Who is on the server and who is on the client?
17
Client Server
View
Controller Model
POSA
Methods won’t be like methods
• How do the model in the server side notify the observer (view) in the client slide?
– Assume a connection is always kept between a client and the server
– Remote proxy
18
Client Server
View
Controller Model
Model Proxy Observer Proxy
DP
Observer Stub Model Stub
Connectionless client server
• Web application – one of the most popular connectionless client-server architecture
– Decode the URLs
– Call the correct methods
– Keep the model state
– Object creation
19
Client (Browser)
Server
View
(AJAX Controller)
Model
Front Controller (Container)
Command (Struts 2 Action)
Session (Container)
PEAA
DP
Persistence
• Two different models
– Object domain model (class diagram)
• Behavior, inheritance, and polymorphism
• Composition with collection (list, map, etc.)
• Direct (dot) navigation
– Data model (ERD for relational databases)
• Composition with foreign key mapping (and relation tables)
• SQL join
– Data mapper
• Extract the persistence logic from the domain model
20
PEAA
Data mapper example
21
+initialize()+exit()+getNavigator() : NavigationModel+getDisplayModel() : ImageDisplayModel+getMotionController() : MotionController+getLanguageManager() : LanguageManager+getPreferences() : Preferences+getViewHistory() : ViewHistory+getReaderManager() : ComicBookSuiteReaderManager+getParallelTaskQueue() : BlockingQueue<Runnable>
<<interface>>core::ComicSurferModel
+initialize(in path : string)+loadLanguage(in name : String) : bool+getLocalizedText(in key : string) : string+getCurrentLanguage() : string+setCurrentLanguage(in name : string) : string+getAvailableLanguages() : Set<string>+addLanguageChangeListener(in listener : LanguageChangeListener)+removeLanguageChangeListener(in listener : LanguageChangeListener)
<<interface>>core::LanguageManager
+setPreference(in key : string, in value : string)+getPreference(in key : string) : string+getPreferenceKeys() : string[]+addPreferencesListener(in listener : PreferencesListener)+removePreferencesListener(in listener : PreferencesListener)
<<interface>>core::Preferences
+getRecordCount() : int+getMaximumRecordCapacity() : int+getLastRecord() : ViewRecord+getRecord(in index : int) : ViewRecord+getRecord(in name : string) : ViewRecord+getRecords() : Iterator<ViewRecord>+setLastViewRecord(in name : string, in uri : URI, in volume : int, in page : int)+setMaximumRecordCapacity() : int+addViewHistoryListener()
<<interface>>core::ViewHistory
+saveHistory(in history : ViewHistory)+loadHistory(in history : ViewHistory)
<<interface>>core::ViewHistoryManager
11
1
1
1
1
1
1
11
+loadPreferences(in preferences : Preferences)+savePreferences(in preferences : Preferences)
<<interface>>core::PreferencesManager
Comic Surfer readers
• Comic surfer supports many formats
– How about ISO, RAR, or comic books on the web?
22
Plug-in architecture pattern
• Plug-in pattern can be seen is many software and platforms
– Eclipse, Firefox, Chrome, etc.
– Extend additional functionalities
• Plug-in can be designed with many techniques
– Reflection for instantiating objects
– Factory method for plug-in initialization
– Strategy for utilizing plug-ins
– Command for invoking functions
– Mediator for plug-in communication
23
PEAA
DP
DP
DP
DP
3rd-party readers management
24
Plug-in
+open()+close()+getPageCount() : int+getPage(in index : int) : Page
<<interface>>core::ComicBook
11..*
+getContent() : InputStream+close()
<<interface>>core::Page
+getComicBookCount() : int+getComicBook(in index : int) : ComicBook+getSuitePath() : string+getSuitePath() : URI+close()+open()
<<interface>>core::ComicBookSuite
11..*
+getDescription() : string+getExtension(in file : File) : string+getSupportedSchemes() : string[]+isFolderReader() : bool+canRead(in uri : URI) : bool+read(in uri : URI) : ComicBookSuite
<<interface>>core::ComicBookSuiteReader
+addReader(in reader : ComicBookSuiteReader)+addReaders(in readers : ComicBookSuiteReader[])+loadThirdPartyReaders(in path : string)+read(in uri : URI) : ComicBookSuite+getBestFitReader(in uri : URI) : ComicBookSuiteReader
<<interface>>core::ComicBookSuiteReaderManager
1*
+createReaders() : ComicBookSuiteReader[]
<<interface>>core::ComicBookSuiteReaderFactory
Strategy
Factory method
Compatibility issue
• When the plug-in API is published
– Any modification could make the existing plug-ins not compatible with the host application
• Eclipse 3.8 Eclipse 4.2
– Adapter
• Great, but whose responsibility?
25
How to adapt the changes?
• This method is NOT silver bullet
– Change interfaces and adapt changes on the abstract classes
26
core::AbstractComicBookSuite core::AbstractComicBook core::AbstractPage
+open()+close()+getPageCount() : int+getPage(in index : int) : Page
<<interface>>core::ComicBook
+getContent() : InputStream+close()
<<interface>>core::Page
1 1..*
+getComicBookCount() : int+getComicBook(in index : int) : ComicBook+getSuitePath() : string+getSuitePath() : URI+close()
<<interface>>core::ComicBookSuite
1 1..*
ThirdPartyComicBookSuite ThirdPartyComicBook ThirdPartyPage
Layer architecture pattern
• When the model becomes more complicated
– The components in the model can be organized in different logical layers
27
http://docs.oracle.com/javase/7/docs/
POSA
Visibility in layer
• Ideally, clients access only the top layer
– For some reasons, clients access the lower layer
– Even the world is not perfect,
• Law of Demeter (Façade)
28
Layer 4
Layer 3
Layer 2
Layer 1 Layer 1
Layer 2
Layer 3
Layer 4
Ideal case Real case
DP
Dependency in layers
• Layer substitution
– I want to change one of the layers, but it is difficult because the upper layer depends on it directly
• Strong dependency between layers
– Why does TCP/IP works?
• Really?
• If you write a C/C++ network program, the TCP interfaces are in different platforms (Unix/Linux socket API vs. WinSocket API)
29
Dependency inversion principle
• Decouple the dependency between layers
– Extract interface
• Two façade, one for the upper client and another for the lower service provider
• Factory or dependency injection (Spring framework)
30
Layer N + 1
Façade for the upper client
Interfaces for the lower service provider
Adapter to the upper layer
Layer N
Façade for the upper client
Interfaces for the lower service provider
Adapter to the upper layer
RF
Dependency inversion example
• The reader layer and streaming layer
31
+run()+stop()+pause()+isRunning() : bool+setSleepTime(in time : unsigned int)
-DEFAULT_IO_SLEEP_TIME : unsigned int-_sleepTime : unsigned int-_stream : TransportStream*
nsc::MediaReader
#synchronize()+readPacket() : TransportPacket
nsc::TransportStream +close()+open() : bool+read() : char+read(in buffer : char*, in length : int) : int+isAvaliable() : bool+isOpened() : bool
<<interface>>nsc::InputStream
* 1
-_dataSocket : Socket*
nsc::NetworkTransportStream nsc::FileInputStream
+connect(in host : string, in port : int)+read(in data : void*, in length : int) : int+write(in data, in length : int) : int+close()
<<interface>>network::Socket
network::BluetoothTCPSocket network::BluetoothUDPSocket network::EthernetSocket
From layers to tiers
• Layers vs. tiers
– A tier is a physical deployment unit
– Web services
– Dependency inversion principle
32
Layer 1
Layer 2
Layer 3
Layer 4 Model Service tier
Presentation tier
Layer 1
Layer 2
Layer 3
Layer 4
Model state
• Which machine should keep the model state?
– May the client cookie or server session help you?
– Duplicate states?
• Database state
• Disposable model objects
– Reduce network overhead
• Data transfer objects
– Transaction
• Unit of work
33
Model Service tier
Presentation tier
Layer 1
Layer 2
Layer 3
Layer 4
PEAA
PEAA
PEAA
Scale up
• Concurrency vs. transaction
– Martin Fowler’s first law of distributed object design: don’t distribute your objects!
34
Model Service tier
Presentation tier
Layer 1
Layer 2
Layer 3
Layer 4
Load Balancer
Load Balancer
Cloud dream
35
http://tedxtaipei.com/talks/2012-simon-chang/
Think different
• Evolutional software architecture is not easy
– Does big design at the start of the project avoid changing the software architecture?
• It depends on the characters of the projects
• Requirements always change
– The following things will help you
• Why do we start from MVC? Domain model design
• Design principles and design patterns
• Unit tests, integration tests, and regression tests
• Continuous integration
• Utilize the frameworks, not be used by them
36
http://zh.wikipedia.org/wiki/Think_Different
Keep on the correct direction
• Evolutional software architecture (refactoring) is an endless story and harmless, not like...
37
Top Related