超級全能危樓改造王
增建、改建、打掉重建你的軟體架構?
Spirit Tu
Senior Program Analyst, GSS
White Day, 2013
2


    • 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
    Taking the Teddy’s courses is one of the fastest ways
             DP           POSA           RF            PEAA




Warning
3




          Alien?




              Do you believe
            evolutional software
               architecture?




I want to believe
4


    • Before the doom, I received the Ph. D. degree




About me
5


    • 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)

The experiences
6




Snapshots of the WiMAX emulator
7


    • 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.

“Big design up front” won this time
8




                                        Mobile Station

             Base Station
                                 Application

      Application                     Socket

         Socket                       Driver

           Driver
                               MAC                                 Single Layer
                                                                    Simulation
    MAC                        SECU
                                                                                           Gateway         UI & Console
    SECU                                                        Agent
                               PHY1
                                               Agent                                                         SYS UI
    PHY1            Agent                                MAC            PHY            Agent
                               PHY2

    PHY2                        CHN                       CHN       MIMO           Routing Table        Conf.     SPMT
                                                                                                       Plug-in    Plug-in
     Data      Control          Data       Control        Data      Control        Data      Control
    Socket     Socket          Socket      Socket        Socket     Socket        Socket     Socket      Control Socket




                             2 sheets of A2 paper class diagram, 15 sheets of A4
                            paper sequence diagrams, and totally over 180k LOC


The architecture
9


    • 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

                          Signal 1

                                                          Signal 2




                                      具DVB-H訊號接受器與
                                                                     具Bluetooth或WiFi之
               DVB-H訊號源              Bluetooth或WiFi之裝置A
                                                                     平板B (需使用本套件)
                                         (需使用本套件)



“Big design up front” won, again
10


     • 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




The things that changed my mindset
11

         always
         usually
         often
     • I sometimes use MVC in a GUI application
         rarely
         never
     • Why do we use MVC?     POSA


       – Separation of concern
       – Focus on the problem domain
       – Reusable model, etc.

Starting from the MVC pattern
12


     • Do we implement the MVC correctly?
        – Are you kidding?
        – In Android, Activity is a model, view, or controller?




      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




MVC implementation is easy?
13


     • 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.


          ATMTextConsole   ATMSwingApp     ATMAndroidApp

             ATMCore         ATMCore          ATMCore
           (100% Tested)   (100% Tested)    (100% Tested)




How to test an Android App?
14


     • Extract method and extract class                         RF




                                                                     View
                                    View

          View
                                                                Controller
                                  Controller
                                                                 Model



                                                         View
         View
                     Controller                Presentation     Controller

                 Model
                                                        Model




Evolution to MVC
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 {              Any problem?

         public CalculatorView(CalculatorModel model) {
             ...
             Nine.Click += new EventHandler(DigitPressed);
         }

         private void DigitPressed(object sender, EventArgs e) {
             Model.InputDigit((Button)sender, ResultTextBox);
         }
     }

An example
16


     • Observer and Strategy pattern                      DP



       – Hollywood Principle: don't call us, we'll call you

                                     View

                     Strategy               Observer           Strategy & Observer



                      Presentation                     Controller


         Program to abstraction                          Program to abstraction



                                     Model
          Direct
          Indirect



Dependencies between MVC
17


     • 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     POSA


       – Who is on the server and who is on the client?
                 Client                  Server


                 View
                                         Model
               Controller




Client-server architecture
18


     • 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 DP
                   Client                        Server

                   View
                                                 Model
                 Controller

         Model Proxy   Observer Stub   Observer Proxy     Model Stub




Methods won’t be like methods
19


     • Web application – one of the most popular
       connectionless client-server architecture
       – Decode the URLs
       – Call the correct methods
       – Keep the model state                 Server

       – Object creation
                                              Model


             Client (Browser)           Session (Container)

                  View              Command (Struts 2 Action)      DP


            (AJAX Controller)       Front Controller (Container)   PEAA




Connectionless client server
20


     • 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      PEAA


          • Extract the persistence logic from the domain model


Persistence
21

                                                                                                                       <<interface>>
                                                                                                                core::PreferencesManager
                                             <<interface>>
                                          core::Preferences                                            +loadPreferences(in preferences : Preferences)
                                                                                          1            +savePreferences(in preferences : Preferences)
                  +setPreference(in key : string, in value : string)
                  +getPreference(in key : string) : string
                  +getPreferenceKeys() : string[]                                                                                 1
                  +addPreferencesListener(in listener : PreferencesListener)                                                      1
                  +removePreferencesListener(in listener : PreferencesListener)
                                                                                                                        <<interface>>
                                                                                              1                   core::ComicSurferModel
                                          <<interface>>
                                     core::LanguageManager                                        +initialize()
                                                                                                  +exit()
         +initialize(in path : string)
                                                                                              1   +getNavigator() : NavigationModel
         +loadLanguage(in name : String) : bool                                           1
                                                                                                  +getDisplayModel() : ImageDisplayModel
         +getLocalizedText(in key : string) : string
                                                                                                  +getMotionController() : MotionController
         +getCurrentLanguage() : string
                                                                                              1   +getLanguageManager() : LanguageManager
         +setCurrentLanguage(in name : string) : string
                                                                                                  +getPreferences() : Preferences
         +getAvailableLanguages() : Set<string>
                                                                                                  +getViewHistory() : ViewHistory
         +addLanguageChangeListener(in listener : LanguageChangeListener)
                                                                                                  +getReaderManager() : ComicBookSuiteReaderManager
         +removeLanguageChangeListener(in listener : LanguageChangeListener)
                                                                                                  +getParallelTaskQueue() : BlockingQueue<Runnable>

                                      <<interface>>                                                                       1
                                    core::ViewHistory                                     1                               1
     +getRecordCount() : int
     +getMaximumRecordCapacity() : int                                                                                 <<interface>>
     +getLastRecord() : ViewRecord                                                                              core::ViewHistoryManager
     +getRecord(in index : int) : ViewRecord                                                             +saveHistory(in history : ViewHistory)
     +getRecord(in name : string) : ViewRecord                                                           +loadHistory(in history : ViewHistory)
     +getRecords() : Iterator<ViewRecord>
     +setLastViewRecord(in name : string, in uri : URI, in volume : int, in page : int)
     +setMaximumRecordCapacity() : int
     +addViewHistoryListener()




Data mapper example
22


     • Comic surfer supports many formats
       – How about ISO, RAR, or comic books on the web?




Comic Surfer readers
23


     • Plug-in pattern can be seen is many software
       and platforms     PEAA


       – 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   DP


       – Strategy for utilizing plug-ins DP
       – Command for invoking functions DP
       – Mediator for plug-in communication DP

Plug-in architecture pattern
24



                                                                                                        Plug-in

                                                                                    <<interface>>
                                                                               core::ComicBookSuite                            <<interface>>
                                                                   +getComicBookCount() : int                               core::ComicBook
                                                                   +getComicBook(in index : int) : ComicBook          +open()
                                                                   +getSuitePath() : string                           +close()
                                                                   +getSuitePath() : URI                       1..*
                                                                                                                 1    +getPageCount() : int
                                                                   +close()                                           +getPage(in index : int) : Page
                                                                   +open()
                                                                                                                                 1
                                                                                                                              1..*

                                                                                                                               <<interface>>
                                                                                     <<interface>>                              core::Page
                            <<interface>>
                                                                            core::ComicBookSuiteReader                +getContent() : InputStream
             core::ComicBookSuiteReaderManager
                                                                   +getDescription() : string                         +close()
     +addReader(in reader : ComicBookSuiteReader)
                                                                   +getExtension(in file : File) : string
     +addReaders(in readers : ComicBookSuiteReader[])
                                                                   +getSupportedSchemes() : string[]
     +loadThirdPartyReaders(in path : string)                 1*   +isFolderReader() : bool                                Strategy
     +read(in uri : URI) : ComicBookSuite
                                                                   +canRead(in uri : URI) : bool
     +getBestFitReader(in uri : URI) : ComicBookSuiteReader
                                                                   +read(in uri : URI) : ComicBookSuite



                                                                                   <<interface>>
                                                                        core::ComicBookSuiteReaderFactory              Factory method
                                                                   +createReaders() : ComicBookSuiteReader[]




3rd-party readers management
25


     • 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?




Compatibility issue
26


     • This method is NOT silver bullet
           – Change interfaces and adapt changes on the
             abstract classes
                   <<interface>>
                                                                   <<interface>>
               core::ComicBookSuite
                                                                  core::ComicBook                             <<interface>>
     +getComicBookCount() : int                                                                                core::Page
                                                          +open()
     +getComicBook(in index : int) : ComicBook
                                                          +close()                                   +getContent() : InputStream
     +getSuitePath() : string                    1 1..*                                     1 1..*
                                                          +getPageCount() : int                      +close()
     +getSuitePath() : URI
                                                          +getPage(in index : int) : Page
     +close()




           core::AbstractComicBookSuite                       core::AbstractComicBook                     core::AbstractPage




            ThirdPartyComicBookSuite                            ThirdPartyComicBook                        ThirdPartyPage




How to adapt the changes?
27


     • When the model becomes more complicated
       – The components in the model can be organized in
         different logical layers POSA




                      http://docs.oracle.com/javase/7/docs/



Layer architecture pattern
28


     • 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)   DP




        Layer 1                           Layer 1


        Layer 2                           Layer 2


        Layer 3                           Layer 3


        Layer 4                           Layer 4
                  Ideal case                        Real case




Visibility in layer
29


     • 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)




Dependency in layers
30


     • Decouple the dependency between layers
       – Extract interface           RF


          • Two façade, one for the upper client and another for
            the lower service provider
          • Factory or dependency injection (Spring framework)
            Façade for the upper client             Adapter to the upper layer
                                          Layer N
                       Interfaces for the lower service provider


            Façade for the upper client             Adapter to the upper layer
                                      Layer N + 1
                       Interfaces for the lower service provider



Dependency inversion principle
31


     • The reader layer and streaming layer
                  nsc::MediaReader
                                                                                                                               <<interface>>
       -DEFAULT_IO_SLEEP_TIME : unsigned int                                                                                 nsc::InputStream
       -_sleepTime : unsigned int                                nsc::TransportStream                          +close()
       -_stream : TransportStream*
                                                                                                               +open() : bool
       +run()                                                                                                  +read() : char
                                                          #synchronize()
       +stop()                                                                                        *    1   +read(in buffer : char*, in length : int) : int
                                                          +readPacket() : TransportPacket
       +pause()                                                                                                +isAvaliable() : bool
       +isRunning() : bool                                                                                     +isOpened() : bool
       +setSleepTime(in time : unsigned int)




                                                             nsc::NetworkTransportStream                                   nsc::FileInputStream
                                                          -_dataSocket : Socket*




                                                                     <<interface>>
                                                                   network::Socket
                                                      +connect(in host : string, in port : int)
                                                      +read(in data : void*, in length : int) : int
                                                      +write(in data, in length : int) : int
                                                      +close()



                        network::BluetoothTCPSocket         network::BluetoothUDPSocket                   network::EthernetSocket




Dependency inversion example
32


     • Layers vs. tiers
        – A tier is a physical deployment unit
        – Web services
        – Dependency inversion principle
                                      Presentation tier
                                     Layer 1
                                     Layer 2
          Layer 1
          Layer 2
          Layer 3
          Layer 4                    Model Service tier
                                     Layer 3
                                     Layer 4




From layers to tiers
33


     • Which machine should keep the model state?
       – May the client cookie or server session help you?
       – Duplicate states?
          • Database state PEAA             Presentation tier
          • Disposable model objects       Layer 1
                                           Layer 2
       – Reduce network overhead
          • Data transfer objects   PEAA


       – Transaction                       Model Service tier
          • Unit of work   PEAA            Layer 3
                                           Layer 4




Model state
34


     • Concurrency vs. transaction
       – Martin Fowler’s first law of distributed object
         design: don’t distribute your objects!

                   Presentation tier    Load Balancer
                   Layer 1
                   Layer 2




                   Model Service tier   Load Balancer
                   Layer 3
                   Layer 4




Scale up
35




              http://tedxtaipei.com/talks/2012-simon-chang/



Cloud dream
36


     • 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

                                              http://zh.wikipedia.org/wiki/Think_Different

Think different
37


     • Evolutional software architecture (refactoring)
       is an endless story and harmless, not like...




Keep on the correct direction

超級全能危樓改造王 - 增建、改建、打掉重建你的軟體架構?

  • 1.
  • 2.
    2 • 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 Taking the Teddy’s courses is one of the fastest ways DP POSA RF PEAA Warning
  • 3.
    3 Alien? Do you believe evolutional software architecture? I want to believe
  • 4.
    4 • Before the doom, I received the Ph. D. degree About me
  • 5.
    5 • 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) The experiences
  • 6.
    6 Snapshots of theWiMAX emulator
  • 7.
    7 • 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. “Big design up front” won this time
  • 8.
    8 Mobile Station Base Station Application Application Socket Socket Driver Driver MAC Single Layer Simulation MAC SECU Gateway UI & Console SECU Agent PHY1 Agent SYS UI PHY1 Agent MAC PHY Agent PHY2 PHY2 CHN CHN MIMO Routing Table Conf. SPMT Plug-in Plug-in Data Control Data Control Data Control Data Control Socket Socket Socket Socket Socket Socket Socket Socket Control Socket 2 sheets of A2 paper class diagram, 15 sheets of A4 paper sequence diagrams, and totally over 180k LOC The architecture
  • 9.
    9 • 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 Signal 1 Signal 2 具DVB-H訊號接受器與 具Bluetooth或WiFi之 DVB-H訊號源 Bluetooth或WiFi之裝置A 平板B (需使用本套件) (需使用本套件) “Big design up front” won, again
  • 10.
    10 • 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 The things that changed my mindset
  • 11.
    11 always usually often • I sometimes use MVC in a GUI application rarely never • Why do we use MVC? POSA – Separation of concern – Focus on the problem domain – Reusable model, etc. Starting from the MVC pattern
  • 12.
    12 • Do we implement the MVC correctly? – Are you kidding? – In Android, Activity is a model, view, or controller? 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 MVC implementation is easy?
  • 13.
    13 • 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. ATMTextConsole ATMSwingApp ATMAndroidApp ATMCore ATMCore ATMCore (100% Tested) (100% Tested) (100% Tested) How to test an Android App?
  • 14.
    14 • Extract method and extract class RF View View View Controller Controller Model View View Controller Presentation Controller Model Model Evolution to MVC
  • 15.
    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 { Any problem? public CalculatorView(CalculatorModel model) { ... Nine.Click += new EventHandler(DigitPressed); } private void DigitPressed(object sender, EventArgs e) { Model.InputDigit((Button)sender, ResultTextBox); } } An example
  • 16.
    16 • Observer and Strategy pattern DP – Hollywood Principle: don't call us, we'll call you View Strategy Observer Strategy & Observer Presentation Controller Program to abstraction Program to abstraction Model Direct Indirect Dependencies between MVC
  • 17.
    17 • 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 POSA – Who is on the server and who is on the client? Client Server View Model Controller Client-server architecture
  • 18.
    18 • 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 DP Client Server View Model Controller Model Proxy Observer Stub Observer Proxy Model Stub Methods won’t be like methods
  • 19.
    19 • Web application – one of the most popular connectionless client-server architecture – Decode the URLs – Call the correct methods – Keep the model state Server – Object creation Model Client (Browser) Session (Container) View Command (Struts 2 Action) DP (AJAX Controller) Front Controller (Container) PEAA Connectionless client server
  • 20.
    20 • 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 PEAA • Extract the persistence logic from the domain model Persistence
  • 21.
    21 <<interface>> core::PreferencesManager <<interface>> core::Preferences +loadPreferences(in preferences : Preferences) 1 +savePreferences(in preferences : Preferences) +setPreference(in key : string, in value : string) +getPreference(in key : string) : string +getPreferenceKeys() : string[] 1 +addPreferencesListener(in listener : PreferencesListener) 1 +removePreferencesListener(in listener : PreferencesListener) <<interface>> 1 core::ComicSurferModel <<interface>> core::LanguageManager +initialize() +exit() +initialize(in path : string) 1 +getNavigator() : NavigationModel +loadLanguage(in name : String) : bool 1 +getDisplayModel() : ImageDisplayModel +getLocalizedText(in key : string) : string +getMotionController() : MotionController +getCurrentLanguage() : string 1 +getLanguageManager() : LanguageManager +setCurrentLanguage(in name : string) : string +getPreferences() : Preferences +getAvailableLanguages() : Set<string> +getViewHistory() : ViewHistory +addLanguageChangeListener(in listener : LanguageChangeListener) +getReaderManager() : ComicBookSuiteReaderManager +removeLanguageChangeListener(in listener : LanguageChangeListener) +getParallelTaskQueue() : BlockingQueue<Runnable> <<interface>> 1 core::ViewHistory 1 1 +getRecordCount() : int +getMaximumRecordCapacity() : int <<interface>> +getLastRecord() : ViewRecord core::ViewHistoryManager +getRecord(in index : int) : ViewRecord +saveHistory(in history : ViewHistory) +getRecord(in name : string) : ViewRecord +loadHistory(in history : ViewHistory) +getRecords() : Iterator<ViewRecord> +setLastViewRecord(in name : string, in uri : URI, in volume : int, in page : int) +setMaximumRecordCapacity() : int +addViewHistoryListener() Data mapper example
  • 22.
    22 • Comic surfer supports many formats – How about ISO, RAR, or comic books on the web? Comic Surfer readers
  • 23.
    23 • Plug-in pattern can be seen is many software and platforms PEAA – 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 DP – Strategy for utilizing plug-ins DP – Command for invoking functions DP – Mediator for plug-in communication DP Plug-in architecture pattern
  • 24.
    24 Plug-in <<interface>> core::ComicBookSuite <<interface>> +getComicBookCount() : int core::ComicBook +getComicBook(in index : int) : ComicBook +open() +getSuitePath() : string +close() +getSuitePath() : URI 1..* 1 +getPageCount() : int +close() +getPage(in index : int) : Page +open() 1 1..* <<interface>> <<interface>> core::Page <<interface>> core::ComicBookSuiteReader +getContent() : InputStream core::ComicBookSuiteReaderManager +getDescription() : string +close() +addReader(in reader : ComicBookSuiteReader) +getExtension(in file : File) : string +addReaders(in readers : ComicBookSuiteReader[]) +getSupportedSchemes() : string[] +loadThirdPartyReaders(in path : string) 1* +isFolderReader() : bool Strategy +read(in uri : URI) : ComicBookSuite +canRead(in uri : URI) : bool +getBestFitReader(in uri : URI) : ComicBookSuiteReader +read(in uri : URI) : ComicBookSuite <<interface>> core::ComicBookSuiteReaderFactory Factory method +createReaders() : ComicBookSuiteReader[] 3rd-party readers management
  • 25.
    25 • 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? Compatibility issue
  • 26.
    26 • This method is NOT silver bullet – Change interfaces and adapt changes on the abstract classes <<interface>> <<interface>> core::ComicBookSuite core::ComicBook <<interface>> +getComicBookCount() : int core::Page +open() +getComicBook(in index : int) : ComicBook +close() +getContent() : InputStream +getSuitePath() : string 1 1..* 1 1..* +getPageCount() : int +close() +getSuitePath() : URI +getPage(in index : int) : Page +close() core::AbstractComicBookSuite core::AbstractComicBook core::AbstractPage ThirdPartyComicBookSuite ThirdPartyComicBook ThirdPartyPage How to adapt the changes?
  • 27.
    27 • When the model becomes more complicated – The components in the model can be organized in different logical layers POSA http://docs.oracle.com/javase/7/docs/ Layer architecture pattern
  • 28.
    28 • 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) DP Layer 1 Layer 1 Layer 2 Layer 2 Layer 3 Layer 3 Layer 4 Layer 4 Ideal case Real case Visibility in layer
  • 29.
    29 • 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) Dependency in layers
  • 30.
    30 • Decouple the dependency between layers – Extract interface RF • Two façade, one for the upper client and another for the lower service provider • Factory or dependency injection (Spring framework) Façade for the upper client Adapter to the upper layer Layer N Interfaces for the lower service provider Façade for the upper client Adapter to the upper layer Layer N + 1 Interfaces for the lower service provider Dependency inversion principle
  • 31.
    31 • The reader layer and streaming layer nsc::MediaReader <<interface>> -DEFAULT_IO_SLEEP_TIME : unsigned int nsc::InputStream -_sleepTime : unsigned int nsc::TransportStream +close() -_stream : TransportStream* +open() : bool +run() +read() : char #synchronize() +stop() * 1 +read(in buffer : char*, in length : int) : int +readPacket() : TransportPacket +pause() +isAvaliable() : bool +isRunning() : bool +isOpened() : bool +setSleepTime(in time : unsigned int) nsc::NetworkTransportStream nsc::FileInputStream -_dataSocket : Socket* <<interface>> network::Socket +connect(in host : string, in port : int) +read(in data : void*, in length : int) : int +write(in data, in length : int) : int +close() network::BluetoothTCPSocket network::BluetoothUDPSocket network::EthernetSocket Dependency inversion example
  • 32.
    32 • Layers vs. tiers – A tier is a physical deployment unit – Web services – Dependency inversion principle Presentation tier Layer 1 Layer 2 Layer 1 Layer 2 Layer 3 Layer 4 Model Service tier Layer 3 Layer 4 From layers to tiers
  • 33.
    33 • Which machine should keep the model state? – May the client cookie or server session help you? – Duplicate states? • Database state PEAA Presentation tier • Disposable model objects Layer 1 Layer 2 – Reduce network overhead • Data transfer objects PEAA – Transaction Model Service tier • Unit of work PEAA Layer 3 Layer 4 Model state
  • 34.
    34 • Concurrency vs. transaction – Martin Fowler’s first law of distributed object design: don’t distribute your objects! Presentation tier Load Balancer Layer 1 Layer 2 Model Service tier Load Balancer Layer 3 Layer 4 Scale up
  • 35.
    35 http://tedxtaipei.com/talks/2012-simon-chang/ Cloud dream
  • 36.
    36 • 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 http://zh.wikipedia.org/wiki/Think_Different Think different
  • 37.
    37 • Evolutional software architecture (refactoring) is an endless story and harmless, not like... Keep on the correct direction