Software Architecture VO/KU (707.023/707.024)
Implementation View
Denis Helic
IWM, TU Graz
Implementation View (1)
- Focuses on how the system is built
- Which technological elements are needed to implement the system
- Software packages, libraries, frameworks, classes, ...
- Addresses non-runtime quality attributes: configurability, testability, reusability, ...
- Again, comprised of components and connectors
Implementation View (2)
- Here, components and connectors reflect software entities and their relationships at the level of source and binary code
- Typically a number of implementation models
- Each model focuses on one of the concurrent subsystems or processes from the execution view
Components in implementation architecture (1)
- Two types of components: application and infrastructure components
- Application components are responsible for implementing domain-level responsibilities
- These are responsibilities found in a detailed conceptual architecture
- Application componentes might be realized as binary packages, source packages, and files
Components in implementation architecture (2)
- Infrastructure components are needed to make the system run but are not related to the application functionality
- E.g. HTTP Connection Handler in MPS system is a typical infrastructure component
- Whether a particular component is an application or an infrastructure component depends on the application
- E.g. if we are building a Web application server then HTTP Connection Handler is an application component
Components in implementation architecture (3)
- Often an infrastructure component acts as a "container" for application components
- A container component provides an execution environment for the contained components
- Typically, the container executes within a process and creates threads for application components
- E.g. a Web application server which runs multiple applications, each of them in their own threads
Component stereotypes in implementation view
(fig. from Reekie book)
Connectors in implementation architecture (1)
- In implementation architecture connectors represent a "uses" relation
- The arrow depicts the direction of this relation
- The nature of communication is depicted through the connector styles
Connectors in implementation architecture (2)
- API call: A component calls a method in another component (possibly only if both components are in the same process)
- Callback: The caller passes a reference of an object to the callee. The callee invokes a method on that object later.
- Network protocol: Needed when implementation components reside in different processes. Components need to agree on a common protocol or use a standradized protocol
- OS signals: Communication between processes running on the same machine
Connectors in implementation architecture (3)
Connector styles (fig. from Reekie book)
Connectors in implementation architecture (4)
- In some cases we depict ports as endpoints of connectors between components
- Ports are used to identify a particular component interface
- E.g. a component might be quite complex but it provides a simple interface for communication
- E.g. the standard Java library provides an API
Implementation architecture: Example
Web server (fig. from Reekie book)
Conceptual vs. Implementation
| Element | Conceptual | Implementation |
| Components | Domain-level responsibilities | Implementation module |
| Connectors | Information flow | "Uses" relationship |
| Views | Single | Split |
Conceptual vs. Execution vs. Implementation
Component relations (Fig. from Reekie book)
Implementation architecture design
- Find application components
- Find infrastructure components
- Interface design
- Behavoir design and verification
Application components (1)
- "Ideal" 1-to-1 mapping of conceptual components onto application components is typically not possible
- Some conceptual components will become infrastructure components
- E.g. persistent storage (databases) are typically infrastructure components
- Some conceptual components are spread over a number of application components
- E.g. conceptual components have complex responsibilities
Application components (2)
- A number of conceptual components can be mapped onto a single application component
- E.g. small number and simple responsibilities
- MPS system is such an example
- UI components map onto one application component (i.e. HTML UI)
- All other map onto a single application component on the server
Infrastructure components (1)
- Off-the-shelf ccomponents
- Frameworks (e.g. application framework)
- Servers (web, application, database, file)
- Generic clients (browser)
- In MPS system two infrastructure components: browser, application server
MPS: Infrastructure components (1)
- Web application server
- Apache Tomcat: http://tomcat.apache.org/
- Reference implementation of the Servlet API
- Servlet API abstracts the HTTP protocol from programmers and allows to write Java classes that handle HTTP requests
MPS: Infrastructure components (2)
public class SomeServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Use "request" to read incoming HTTP headers (e.g. cookies)
// and HTML form data (e.g. data the user entered and submitted)
// Use "response" to specify the HTTP response line and headers
// (e.g. specifying the content type, setting cookies).
PrintWriter out = response.getWriter();
// Use "out" to send content to browser
}
}
MPS: Infrastructure components (3)
- With a servlet we can read parameters from the user
- E.g. answers in our MPS
- We can respond with HTML
- E.g a new panel in our MPS
Interface design (1)
- For all application and infrastructure components we need to define interfaces (ports)
- Helps in claryfing the responsibilites of a component
- Some interfaces are also standardized
- E.g. HTTP, SQL, File I/O
MPS: Interface design (1)
- UI: Combination of HTML/HTTP
- It is standardized!
- Web application server: HTTP/Servlet API
- It is standardized
MPS: Interface design (2)
- MPS application running on the server
- A new interface is needed
- We need to tell to the system that answers are there and it should calculate the next step
- e.g. execute(answers)
MPS: Interface design (3)
- We should also tell to the system where to write output
- Therefore execute(answers, html_panel)
- Lastly, we need a mechanism to connect questions to answers
- e.g. panel.getQuestions()
Behavior design
- Now we need to go into details
- Use-case maps are not enough anymore
- We need to investigate behaviour at the operation level
- Thus, we need a sequence diagram
MPS: Implementation Architecture (1)
MPS: Implementation Architecture (2)
MPS: Interface Sequence Diagram
Non-runtime quality attributes
- Since implementation view addresses build structure
- It is the right place to consider non-runtime quality attibutes
- E.g. maintability, extensibility, reusability, ...
- We can use a mechanism similar to use-case maps
- Impact-maps: try to investigate what parts of the system need to change if "something" happens
Impact-maps
- Map 1: new external system - interface to external system needs to be changed
- Map 2: new application - application component needs to be changed
- Map 3: new UI - UI component needs to be changed
- Goal: as few component changes as possible
Prototype
- To show that the architectural solution is feasible we implement prototypes
- For each identified application component we provide implementation
- Deploy it within the infrastructure components
- Test it and check correctness, functionality, quality-attributes
Implemention Example: MPS
- The next 21 slides serve only as illustration and are not discussed in detail during the lecture!
Implementation
- Depending on the nature of an application component different implementation strategies
- We have a Web-based UI component: simple HTML pages
- Application component on the server: OO programming with Java
- Now we need to make OO design and implementation
- By following general OO and OO design rules
- Document with UML: sequence diagrams, class diagrams, etc...
MPS design (1)
- MPS is a system that leads the user through a number of steps
- How to proceed depends on the user input
- I.e. the application has a number of states and how to switch between states depends on the user input
- Most easily modelled with a so-called state machine
MPS: state machine (configuration system)
| State/Choice | 0 | 1 |
| Initial | -1 | 1 |
| ToolSelection | 2 | - |
| ToolParameters | 0 | - |
MPS design (2)
- But we want to abstract this from the application
- We will have an Application class which handles the transition table
- We will need also a State class to encapsulate an application state
- Obviously, we will need a StatePanel class to represent a state to the user
MPS design (3)
- We will also need abstraction of question and answers for the user input
- Since we do not know what types of question and answers we will have we need to have abstract classes
- Also, we do not know how answers are processed - thus we will need to abstract this as well
- We need to abstract also the actions taken because we do not know external systems
MPS design (4)
- A particular application will need to inherit, compose, etc...
- Of course, to ensure that OO design rules are followed
- Our abstract framework must not be changed when there is a new application
- Recollect open/closed principle
MPS: class diagram (1)
MPS: class diagram (2)
MPS: class diagram (3)
MPS: class diagram (4)
MPS: class diagram (5)
MPS: Application execute
if(!isFinalState()) {
State current_state = getCurrentState();
if(current_state.execute(answers)) {
state_number_ = transition_[state_number_]
[current_state.getChoice()];
...
} else {
current_state.displayErrorMessage(panel);
}
panel.showPanel();
}
MPS: Application subclasses
protected void init(Map<String, String> parameters) {
states_ = new State[4];
states_[0] = new InitialState();
states_[1] = new ToolSelectionState(cf_path + "config.txt");
states_[2] = new ToolParametrizationState(cf_path + "config.txt");
transition_ = new int[3][2];
transition_[0][0] = -1;
transition_[0][1] = 1;
transition_[1][0] = 2;
transition_[2][0] = 0;
...
}
MPS: State execute
final public boolean execute(List<Answer> answers) {
setAnswers(answers);
if(!areAnswersCorrect()) {
return false;
}
processActionAnswers();
processChoiceAnswers();
return true;
}
MPS: Checking answers
private boolean areAnswersCorrect() {
for(Question question : questions_) {
if(!question.isAnswerCorrect()) {
return false;
}
}
return true;
}
MPS: Questions
public Question(String question, AnswerChecker checker) {
this(question);
checker_ = checker;
}
public boolean isAnswerCorrect() {
if(checker_ != null) {
return checker_.isAnswerCorrect(answer_.toString());
}
return true;
}
MPS: Questions (OC Principle)
public class NonEmptyAnswerChecker implements AnswerChecker {
public String getErrorMessage() {
return "Answer can not be empty";
}
public boolean isAnswerCorrect(String answer) {
if((answer == null) || (answer.length() == 0)) {
return false;
}
return true;
}
}
MPS: State subclasses
protected void makeQuestions() {
List<String> tools = new ArrayList<String>();
tools.add("Wiki");
tools.add("Blog");
..
}
protected void processChoiceAnswers() {
choice_ = 0;
}
protected void processActionAnswers() {
Answer answer = questions_.get(0).getAnswer();
WriteConfigFileAction action = new WriteConfigFileAction(path_,
answer.toString() + ":\n");
action.executeAction();
}
MPS: Actions (new thread)
public abstract class Action implements Runnable {
private boolean started_ = false;
public void executeAction() {
start();
}
private void start() {
if(!started_) {
started_ = true;
Thread thread = new Thread(this);
thread.start();
}
}
public void run() {
execute();
}
abstract protected void execute();
}
MPS: Action subclasses
protected void execute() {
try {
FileWriter writer = new FileWriter(path_, true);
writer.write(message_);
writer.flush();
writer.close();
} catch (IOException exc) {
exc.printStackTrace();
throw new RuntimeException(exc);
}
}
Implementation Example End
- The last 21 slides serve only as an illustrative example and are not discussed in detail during the lecture
Implementation arch. summary
What you need to submit:
- Detailed implementation architecture with app, infrastructure and interfaces
- Sequence diagram of application interfaces
Prototype summary
What you need to submit:
- Class diagrams
- Sequence diagrams
- Code
Model-View-Controller (1)
- Model-View-Controller is a particular architectural design pattern that supports SOC
- It was invented in the early days of GUIs
- To decouple the graphical interface from the application data and logic
- GUI is further separated into data presentation and users' input
- Invented at Xerox Parc in the 70's
Model-View-Controller (2)
- The first appereance in Smalltalk-80
- One of the first OO languages
- Pure OO language, i.e., everything is an object
- MVC invented by Trygve Reenskaug: Original documentation
Model-View-Controller (3)
Model-View-Controller (4)
- Controller
- Handles user input (e.g., mouse clicks, keyboard,...)
- Updates the model
- Instructs the view to redraw itself
Model-View-Controller (5)
- View
- Presents the model in a specific way
- Note different views for the same model
- Very important not only in GUIs but also in Web applications (e.g., XHTML, PDF, etc.)
Model-View-Controller (6)
- Model
- Contains the data and application logic
Model-View-Controller (7)
- Very easily accomplished with an OO programming model
- Objects encapsulate the data
- Objects implement behaviour (as methods)
- Interaction between different objects (i.e., invoking methods) supports the application logic
Model-View-Controller (8)
- Where does the data come from?
- If in memory - everything is covered
- If in the file system or in a DBMS
- We need a special Data Management module
Model-View-Controller (9)
IA 1: Observer Pattern (1)
- A special case of the MVC uses Observer design pattern
IA 1: Observer Pattern (2)
- When the model changes it notifies the views about the change
- All views redraw as the result of the notification
- Until Ajax not applicable in a Web application
- Page-oriented applications
- You need a user request for each particular view (e.g., HTML, PDF,..)
- With Ajax it is possible (Asynchronous request)
- It improves the responsiveness of a Web app tremendously
IA 1: Observer Pattern (3)
- The purpose of the controller is not to separate the model from the view
- E.g., in GUI applications the purpose of the controller is to handle user events
- To achieve this separation another design pattern is needed
- Typically acheived by means of the Observer pattern
MVC: An example with Observer pattern (1)
- A simple GUI Java application using MVC
- The example uses Observable/Observer pair from java.util
- Subclasses of the Observable class can notify observers about changes in their state
- Implementation classes of Observer need to implement update() method to react to the changes
- Observer is a Java interface
MVC: An example with Observer pattern (2)
- Model
- SimpleModel holding a single integer value
- getValue() and setValue() methods to manipulate the model
- The value must be in the range [0,100]
MVC: An example with Observer pattern (3)
final public class SimpleModel extends Observable {
...
public void setValue(int value) {
if ((value > 100) || (value < 0)) {
throw new IllegalArgumentException("The value must be ..");
}
value_ = value;
setChanged();
notifyObservers();
}
...
}
Source code
MVC: An example with Observer pattern (4)
- View
- Holds a reference to the model
- Manages a GUI widget to represent the model value
- Reacts to change notifications from the model
- It is an abstract class, where subclasses manage different GUI widgets
MVC: An example with Observer pattern (5)
public abstract class SimpleView implements Observer {
protected JComponent widget_;
public void update(Observable observable, Object arg) {
updateView();
}
abstract public void updateView();
...
}
Source code
MVC: An example with Observer pattern (6)
final public class SimpleTextFieldView extends SimpleView {
private JTextField value_field_ = new JTextField();
public SimpleTextFieldView(SimpleModel model) {
...
widget_ = new JPanel(new BorderLayout());
...
widget_.add(value_field_, BorderLayout.SOUTH);
}
public void updateView() {
value_field_.setText("" + model_.getValue());
}
}
Source code
MVC: An example with Observer pattern (7)
public class SimpleSliderView extends SimpleView {
private JSlider value_slider_ = new JSlider();
public SimpleSliderView(SimpleModel model) {
...
widget_ = new JPanel(new BorderLayout());
...
widget_.add(value_slider_, BorderLayout.SOUTH);
}
public void updateView() {
value_slider_.setValue(model_.getValue());
}
}
Source code
MVC: An example with Observer pattern (8)
- Controller
- Java Event System follows already MVC, i.e., it is the controller
- The event capturer forwards a captured event (e.g. a mouse click) to the event dispatcher
- The event dispatcher manages a mapping of events to event listeners
- The event dispatcher finds the proper listener and invokes its actionPerformed() method
- We need only to write listeners, register them with GUI widgets and implement action() methods
MVC: An example with Observer pattern (9)
final public class SimpleTextFieldView extends SimpleView {
public SimpleTextFieldView(SimpleModel model) {
...
value_field_.addActionListener(new TextFieldControllerAction());
...
}
class TextFieldControllerAction implements ActionListener {
public void actionPerformed(ActionEvent event) {
model_.setValue(Integer.parseInt(value_field_.getText()));
}
}
}
Source code
MVC: An example with Observer pattern (10)
public class SimpleSliderView extends SimpleView {
public SimpleSliderView(SimpleModel model) {
...
value_slider_.addChangeListener(new SliderControllerAction());
...
}
class SliderControllerAction implements ChangeListener {
public void stateChanged(ChangeEvent event) {
model_.setValue(value_slider_.getValue());
}
}
}
Source code
MVC: An example with Observer pattern (11)
public static void main(String[] args) {
SimpleModel model = new SimpleModel();
SimpleView view = new SimpleTextFieldView(model);
...
view = new SimpleSliderView(model);
...
model.setValue(12);
}
Source code
Complete source code
MVC on the server side (1)
- The server recieves different HTTP requests
- Requests can include different parameters submitted by the user
- On the basis of these parameters the server produces the response
- The server can dispatch the request to different handlers (actions)
- The server needs a registry of mappings of parameters onto actions
- The server, registry, dispatcher and actions are the Controller
MVC on the server side (2)
- The Model is accessed from the actions
- It is data and behaviour encapsulated within objects
- Each action is associated with a View
- When the action finishes the Controller invokes the View
- The View accesses the Model, retrieves (!) the data and present it
- The registry includes also associations between actions and views
Struts - Java-based MVC Web App Framework (1)
Struts - Java-based MVC Web App Framework (1)
Struts - Java-based MVC Web App Framework (2)
- Download
- You can download either binaries or sources
- In the installation included: struts-blank.war
- You can use it for a quick start with Struts
- Only edit struts-config.xml and define your own actions
- Everything else is in place
Struts - Java-based MVC Web App Framework (3)
- Defining actions in struts-config.xml has a number of steps
- Defining a URL pattern for that action (pattern + .do)
- Defining a so-called ActionForm which encapsulates the user parameters
- There is a special JavaBean class that extends ActionForm class
- This class provides getters and setters for the parameters (same names)
- Defining a number of forwards to JSP pages to present the results
Struts - Java-based MVC Web App Framework (4)
<action-mappings>
...
<action
path="/search"
type="edu.iicm.publication.struts.SearchAction"
name="search_form"
scope="request"
validate="false"
input="/search.jsp">
<forward name="html" path="/search_results.jsp"/>
<forward name="bibtex" path="/search_export.jsp"/>
<forward name="rdf" path="/search_export.jsp"/>
</action>
...
</action-mappings>
Struts - Java-based MVC Web App Framework (5)
- If validate set to true then you can validate that the user parameters have the proper values
- Need to implement the validate() method inside your ActionForm subclass
- If validation fails
- The user is redirected to JSP specified in the input attribute
Struts - Java-based MVC Web App Framework (6)
- Name parameter refers to the ActionForm subclass
<form-beans>
...
<form-bean
name="search_form"
type="edu.iicm.publication.struts.SearchForm"/>
...
</form-beans>
Struts - Java-based MVC Web App Framework (7)
- Additionally, Java classes need to be implemented
- ActionForm subclass encapsulating parameters
- A subclass of the Action class which manipulates the Model objects
- Here you also decide to which JSP page to forward
- Finally, a number of JSP pages to present the results
Ruby on Rails (1)
- Ruby is a pure object-oriented programming language
- http://www.ruby-lang.org/en/
- Pure means everything is an object, e.g. the number 1 is an instance of class Fixnum
- Interpreted scripting language
- Dynamically, weakly typed
- Single inheritance, but can be extended with so-called modules (similar to Java interfaces)
- Rich text processing functionality (similar to Perl)
Ruby on Rails (2)
- Rails is open source Web application framework
- http://www.rubyonrails.org/
- Supports development of database-backed application
- User-oriented Web database applications
- Follows MVC architecture and design pattern
Ruby on Rails (3)
- Three main guiding principles
- Model-driven (domain-driven) development
- You start with a data model and add the functionality, controllers, views on top of it
- Convention over configuration
- Set of naming conventions (similar to JavaBeans but more in depth)
- Less software, i.e., less code
- Generating default code that you adjust to fit your needs
Ruby on Rails (4)
- Domain-driven development
- Based on an ORM framework called ActiveRecord
- http://wiki.rubyonrails.com/rails/pages/ActiveRecord
- ActiveRecord is a generic ORM framework
- Similar to Hibernate
- Uses a naming convention to provide the default mapping
- You can adjust the default mapping if you need to
Ruby on Rails (5)
- ActiveRecord naming convention
- Names of classes and tables
- Give names to your classes as English singular, and to your tables as English plural
- Start the name of the class with an upper case, all other letters are lower case (Student)
- Table name is all lower case (students)
Ruby on Rails (6)
class Student < ActiveRecord::Base
end
create table students (
id int not null auto_increment,
name varchar(80),
study_field varchar(10),
primary key(id)
);
Ruby on Rails (7)
- Names of the table columns and instance variables
- Map 1-to-1, i.e., student.name maps to name column in students
- Primary key must be named id in the table
- Immediatelly you can use all methods from ActiveRecord
@students = Student.find_all
@student = Student.new
Ruby on Rails (8)
- Internally, ActiveRecord uses a single table to map the whole class hierarchy
- To map associations a simple domain language-like set of macros is used
Ruby on Rails (9)
class Student < ActiveRecord::Base
has_and_belongs_to_many :courses
end
- Connects two classes via an associative table (many-to-many relation)
- The name of the table: courses_students
- The names of foreign keys: course_id, student_id
Ruby on Rails (10)
- Convention over configuration
- A lot of examples in ActiveRecord
- Further examples in controller module of MVC
- Controllers are modules that handle user requests
- Convention on mapping of URLs onto methods in controllers
- Much easier than Struts configuration
Ruby on Rails (11)
class TestController < ApplicationController
def index
render_text "Wow, that was easy"
end
def hello
render_text "Hello World"
end
end
Ruby on Rails (12)
- Whenever you have a model class, e.g., Student class you can use a so-called CRUD scaffold
- create, read, update, delete methods
- These methods are provided by the ActiveRecord
class StudentController < ApplicationController
scaffold :student
end
Ruby on Rails (14)
- By scaffolding you also get default views
- However, you can adjust them
- For a particular controller method, e.g., show() you need to create show.rhtml
- Another naming convention