Design ECE 417617 Elements of Software Engineering Stan

  • Slides: 58
Download presentation
Design ECE 417/617: Elements of Software Engineering Stan Birchfield Clemson University

Design ECE 417/617: Elements of Software Engineering Stan Birchfield Clemson University

From modeling to design Steps: 1. Analysis and modeling 2. Design 3. Construction (code

From modeling to design Steps: 1. Analysis and modeling 2. Design 3. Construction (code generation and testing) Design involves making the analysis model more specific, to facilitate construction. Goal of design is quality.

FURPS Quality software is • Functional – capabilities of program • Usable – human

FURPS Quality software is • Functional – capabilities of program • Usable – human factors, aesthetics • Reliable – frequency and severity of failure • Performance – response time, speed • Supportable – is the code maintainable, extensible, testable, configurable, easy to install, etc. (Developed by Hewlett-Packard in 1980 s)

Basic design principles • Design is iterative: – – – • Architecture is refined

Basic design principles • Design is iterative: – – – • Architecture is refined over time by successively filling in details Refinement is a process of elaboration Results in hierarchical model A good design exhibits – – – abstraction – details are provided in lower levels modularity – divide-and-conquer via smaller independent components refactoring – internal structure of software is improved without affecting external behavior

Design model has three aspects: • Architectural design • Component-level (data) design • Interface

Design model has three aspects: • Architectural design • Component-level (data) design • Interface design We will consider these in turn, with UI covered in a separate lecture.

Architectural Design

Architectural Design

Architectural design • Architecture is a high-level representation of the S/W with the major

Architectural design • Architecture is a high-level representation of the S/W with the major components identified Architectural styles are templates, e. g. , • – – – • Data-centered Data-flow Call and return Object-oriented Layered Architectural patterns define specific approach for handling some behavioral characteristic of system, e. g. , – – – concurrency: use O/S features or provide task scheduler persistence: storage and retrieval of data distribution: communication of components with one another. Most common is broker – acts as middle man between client and server (CORBA). Style is like “Cape cod, A-frame”. Pattern is like “kitchen”.

Architectural Styles • Data-centered – subsystems interact through single repository • Model / View

Architectural Styles • Data-centered – subsystems interact through single repository • Model / View / Controller • Call and return (Client / Server) • Layered (three-tier, four-tier) • Data-flow (pipe and filter)

Layers and Partitions • Layer – group of related subsystems – Layer knows about

Layers and Partitions • Layer – group of related subsystems – Layer knows about layers below it, but not layers above it – Top layer: no one else knows about it – Closed architecture – can only access layer immediately below – Open architecture – can access any layer below • Partition – peer subsystems, each with different responsibilities

Hierarchical decomposition Application Format Object Level of abstraction Presentation CORBA Connection Session Message Transport

Hierarchical decomposition Application Format Object Level of abstraction Presentation CORBA Connection Session Message Transport Socket Packet Network TCP/IP Frame Data. Link Physical Ethernet Wire Bit Example: Open Systems Interconnection (OSI)

Mapping DFD into architecture • Transform mapping – – – – • transform flow

Mapping DFD into architecture • Transform mapping – – – – • transform flow always exists; represents information flow within system; incoming flow passes through transform center, leads to outgoing flow To map DFD with transform flow characteristics into specific architectural style, review model refine models determine whether transform or transaction characteristics isolate transform center perform first and second level factoring refine Transaction mapping – – – – transaction flow occurs when one input gives rise to several outputs; transaction triggers data flow along one of many paths To map DFD with transaction flow characteristics, review model refine models determine whether transform or transaction characteristics isolate transaction center map to transform branch factor and refine

Model / View / Controller (MVC) • MVC: – Model subsystems maintain domain knowledge

Model / View / Controller (MVC) • MVC: – Model subsystems maintain domain knowledge – View subsystems display it to the user – Controller subsystems manage sequence of interactions with user • M doesn’t depend upon V or C • Changes propagated via subscribe/notify protocol, using Observer design pattern • Well-suited for interactive systems

MVC Details Controller initiator 1 * repository Model 1 View subscriber * notifier

MVC Details Controller initiator 1 * repository Model 1 View subscriber * notifier

MVC Example

MVC Example

MVC Example Details 2: enter. New. File. Name(file, new. Name) 3: set. Name(new. Name)

MVC Example Details 2: enter. New. File. Name(file, new. Name) 3: set. Name(new. Name) : Controller 1: subscribe. To. File. Events(file) 5: get. Name() : Info. View : Model 4: notify. Subscribed. Views(file) : Folder. View 1: subscribe. To. File. Events(file) 5: get. Name()

GUI-Based Programming

GUI-Based Programming

Paradigms Compared Application output callbacks draw Widgets Application input output input The User Traditional

Paradigms Compared Application output callbacks draw Widgets Application input output input The User Traditional command-line GUI-based

Event/Message loop

Event/Message loop

Event loop – pseudocode int main() { return Win. Main(); } Win. Main() {

Event loop – pseudocode int main() { return Win. Main(); } Win. Main() { while (1) { // loop forever, waiting for an event if (event_exists) { //there is an event, figure out what to do if (event == keydown_a) display(‘user pressed the A key’); else if (event == window_resize) display(‘window resized’); else if (event == repaint) display(‘need to repaint window’); else if (event == keydown_escape) exit_program(); } } }

Event loop – Win. Main int WINAPI Win. Main (HINSTANCE h. Inst, HINSTANCE h.

Event loop – Win. Main int WINAPI Win. Main (HINSTANCE h. Inst, HINSTANCE h. Prev. Inst, char * cmd. Param, int cmd. Show) { char class. Name [] = "Winnie"; Win. Class win. Class (Window. Procedure, class. Name, h. Inst); win. Class. Register (); Win. Maker win ("Hello Windows!", class. Name, h. Inst); win. Show (cmd. Show); MSG msg; int status; while ((status = : : Get. Message (& msg, 0, 0, 0)) != 0) { if (status == -1) return -1; : : Dispatch. Message (& msg); } return msg. w. Param; }

Event loop – Window. Proc LRESULT CALLBACK Window. Procedure (HWND hwnd, unsigned int message,

Event loop – Window. Proc LRESULT CALLBACK Window. Procedure (HWND hwnd, unsigned int message, WPARAM w. Param, LPARAM l. Param) { switch (message) { case WM_DESTROY: : : Post. Quit. Message (0); return 0; } return : : Def. Window. Proc (hwnd, message, w. Param, l. Param ); }

Event loop (cont. ) int WINAPI Win. Main(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int

Event loop (cont. ) int WINAPI Win. Main(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow) { HWND hwnd; MSG msg; //initialization code goes here while(1) { // Get message(s) if there is one if(Peek. Message(&msg, hwnd, 0, 0, PM_REMOVE)) { if(msg. message == WM_QUIT) break; Translate. Message(&msg); Dispatch. Message(&msg); //this calls the CALLBACK function Win. Proc() } else { Draw. Scene(); //display the Open. GL/Direct. X scene } } }

Event loop (cont. ) LRESULT CALLBACK Win. Proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM

Event loop (cont. ) LRESULT CALLBACK Win. Proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { PAINTSTRUCT ps; // Depending on the message -- we'll do different stuff switch(message) { case WM_PAINT: Draw(); return 0; // ESC will quit program case WM_KEYDOWN: //user pressed a key if(Get. Async. Key. State(VK_ESCAPE)) //it was the escape key Post. Quit. Message(0); //quit program return 0; case WM_DESTROY: //windows wants the program to die case WM_CLOSE: //or the user closed the window Post. Quit. Message(0); //quit program return 0; } return Def. Window. Proc(hwnd, message, wparam, lparam); }

GUI Concepts • Widget – graphic object with functionality; e. g. , button, toolbar,

GUI Concepts • Widget – graphic object with functionality; e. g. , button, toolbar, . . . • Window – holds widgets • Child/parent – relationships between windows • Event / message – how windows communicate

Anatomy of a Window title bar menu toolbar client area status bar

Anatomy of a Window title bar menu toolbar client area status bar

Microsoft Windows Programming • History: – Win 32 API: core library written in C

Microsoft Windows Programming • History: – Win 32 API: core library written in C – MFC: C++ wrappers around most common Win 32 API functions • • Lots of macros Lots of legacy code Not free, not portable But it works (generally speaking)

Analyzing architectural designs Two approaches developed by SEI: • Architecture trade-off analysis method (ATAM)

Analyzing architectural designs Two approaches developed by SEI: • Architecture trade-off analysis method (ATAM) – Collect scenarios and requirements – Evaluate quality attributes and their sensitivity – Critique candidate architectures • Scenario-based architectural analysis (SAAM) – Uses scenarios to analyze architectures with respect to quality attributes Quality attributes: reliability, performance, security, maintainability, flexibility, testability, portability, reusability, interoperability

Component-level Design

Component-level Design

Component-level design • Occurs after the first iteration of architectural design Goal: translate the

Component-level design • Occurs after the first iteration of architectural design Goal: translate the design model into operational software Component is set of collaborating classes Designing components • • • – – OCL flow chart tabular design notation Decision table has four quadrants specifying conditions and actions, as well as rules for both PDL (pseudocode)

Decomposition System Subsystem 1 Class 1 a . . . Class 1 n .

Decomposition System Subsystem 1 Class 1 a . . . Class 1 n . . . Subsystem. N Class. Na . . . Class. Nn

Coupling and cohesion • Coupling -- # of dependencies between subsystems • Cohesion --

Coupling and cohesion • Coupling -- # of dependencies between subsystems • Cohesion -- # of dependencies within subsystem • Goal: low coupling, high cohesion • 7 +/- 2 rule – keep number of concepts at any given layer of abstraction bounded

Additional design principles • • Single responsibility (SRP) A class should have only one

Additional design principles • • Single responsibility (SRP) A class should have only one reason to change Open-closed (OCP) Software entities should be open for extension but closed for modification (achieved via inheritance) Liskov substitution (LSP) Subclasses should be substitutable for their base classes Dependency inversion (DIP) Abstractions should not depend upon details Interface segregation (ISP) Many client-specific interfaces are better than one general purpose interface Release reuse equivalency (REP) Granule of reuse is granule of release Common closure (CCP) Classes that change together belong together Common reuse (CRP) Classes in a package are reused together

Data structures and flow • Software system is composed of – data structures, and

Data structures and flow • Software system is composed of – data structures, and – data flow • Which is more important? “Show me your code and conceal your data structures, and I shall continue to by mystified. Show me your data structures and I won’t usually need your code. It will be obvious. ” – Fred Brooks

What is a Design Pattern? • A design pattern – abstracts a recurring design

What is a Design Pattern? • A design pattern – abstracts a recurring design structure – comprises class and/or object • • dependencies, structures, interactions, or conventions – distills design experience

Re-use • Code re-use – Don’t reinvent the wheel – Requires clean, elegant, understandable,

Re-use • Code re-use – Don’t reinvent the wheel – Requires clean, elegant, understandable, general, stable code – leverage previous work • Design re-use – Don’t reinvent the wheel – Requires a precise understanding of common, recurring designs – leverage previous work

Some design patterns • • • Abstract factory Adapter Bridge Command Composite Façade Subject

Some design patterns • • • Abstract factory Adapter Bridge Command Composite Façade Subject / Observer Proxy Strategy

Subject-observer [from Vlissides]

Subject-observer [from Vlissides]

Subject-observer (cont. ) Subject Register(Observer) Unregister(Observer) Notify. All() 1 * Observer On. Update() for

Subject-observer (cont. ) Subject Register(Observer) Unregister(Observer) Notify. All() 1 * Observer On. Update() for all o in observers { o. On. Update() }

Subject-observer (cont. ) Subject Register(Observer) Unregister(Observer) Notify. All() Concrete. Subject 1 * Observer virtual

Subject-observer (cont. ) Subject Register(Observer) Unregister(Observer) Notify. All() Concrete. Subject 1 * Observer virtual On. Update() for all o in observers { o. On. Update() } Concrete. Observer virtual On. Update()

Model / view / controller (MVC) Model } On. Update() calls Register() Set() Controller

Model / view / controller (MVC) Model } On. Update() calls Register() Set() Controller (holds data) Set() View Create() Main Model m; Controller c(&m); View v(&c); Register() Model { (mediates) Create() Controller (displays data) Create() View

MVC (cont. ) Subject Register(Observer) Unregister(Observer) Notify. All() Controller 1 * Observer virtual On.

MVC (cont. ) Subject Register(Observer) Unregister(Observer) Notify. All() Controller 1 * Observer virtual On. Update() for all o in observers { o. On. Update() } View virtual On. Update()

MVC (cont. ) class Observer { protected: virtual void On. Update(Msg. Id message_id) =

MVC (cont. ) class Observer { protected: virtual void On. Update(Msg. Id message_id) = 0; }; class Subject { public: enum Msg. Id {}; void Register. Observer(Observer* obs); virtual void Notify. All. Observers(Msg. Id message_id) { for (int i=0 ; i<m_observers. size() ; i++) { m_observers[i]->On. Update(message_id); } } private: std: : vector<Observer*> m_observers; };

MVC (cont. ) class Controller : public Subject { Controller(Data* d) : m_data(d) {}

MVC (cont. ) class Controller : public Subject { Controller(Data* d) : m_data(d) {} const Data* Get. Data() const; void Add. Sphere(const Sphere& s) { m_data->Add. Sphere(s); Notify. All. Observers(ADD_SPHERE); } private: Data* m_data; };

MVC (cont. ) class Main. Wnd : public Observer, CWnd { public: Main. Wnd(Controller*

MVC (cont. ) class Main. Wnd : public Observer, CWnd { public: Main. Wnd(Controller* c) : m_controller(c) { c. Register(this); } virtual void On. Update(int message_id) { switch (message_id) { case Subject: : ADD_SPHERE: . . . } } private: Controller* m_controller; };

Adapter • You have – legacy code – current client • Adapter changes interface

Adapter • You have – legacy code – current client • Adapter changes interface of legacy code so client can use it • Adapter fills the gap b/w two interfaces • No changes needed for either – legacy code, or – client

Adapter (cont. ) class New. Time { public: int Get. Time() { return m_oldtime.

Adapter (cont. ) class New. Time { public: int Get. Time() { return m_oldtime. get_time() * 1000 + 8; } private: Old. Time m_oldtime; };

Command • You have commands that need to be – executed, – undone, or

Command • You have commands that need to be – executed, – undone, or – queued • Command design pattern separates – Receiver from Invoker from Commands • All commands derive from Command implement do(), undo(), and redo()

Implementing ‘Undo/Redo’ • Multi-level undo/redo requires two classes: – Command. Manager class Command {

Implementing ‘Undo/Redo’ • Multi-level undo/redo requires two classes: – Command. Manager class Command { public: virtual bool Execute() = 0; virtual bool Unexecute() = 0; virtual ~Command() { } }; class Command. Manager { private: typedef list<Command*> Command. List; Command. List m_undo. List; Command. List m_redo. List; public: void Do. Command(Command* com); void Undo(); void Redo(); }; http: //www. codeproject. com/KB/cpp/undoredo_cpp. aspx

Facade • You – have a set of related classes – want to shield

Facade • You – have a set of related classes – want to shield the rest of the system from these details • Facade provides a simplified interface • Encapsulates a subsystem

Composite • You want uniformly to treat – items (atomic elements), and – groups

Composite • You want uniformly to treat – items (atomic elements), and – groups (containing items or other groups) • Composite interface specifies operations that are shared between items and groups • Examples: hierarchy of files and directories, groups of drawable elements

Composite (cont. ) Composite Item Group

Composite (cont. ) Composite Item Group

Proxy • You want to – delay expensive computations, – use memory only when

Proxy • You want to – delay expensive computations, – use memory only when needed, or – check access before loading an object into memory • Proxy – has same interface as Real object – stores subset of attributes – does lazy evaluation

Strategy • You want to – use different algorithms depending upon the context –

Strategy • You want to – use different algorithms depending upon the context – avoid having to change the context or client • Strategy – decouples interface from implementation – shields client from implementations – Context is not aware which strategy is being used; Client configures the Context – strategies can be substituted at runtime – example: interface to wired and wireless networks

Strategy (cont. ) Client Policy Context Strategy Concrete Strategy. A Concrete Strategy. B

Strategy (cont. ) Client Policy Context Strategy Concrete Strategy. A Concrete Strategy. B

Strategy (cont. ) Lots of switch statements is evidence of “code smell”: Polymorphism, using

Strategy (cont. ) Lots of switch statements is evidence of “code smell”: Polymorphism, using strategy pattern, cleans this up: http: //codebetter. com/blogs/jeremy. miller/archive/2006/04/11/142665. aspx

Bridge • You – have several different implementations – need to choose one, possibly

Bridge • You – have several different implementations – need to choose one, possibly at run time • Bridge – decouples interface from implementation – shields client from implementations – Abstraction creates and initializes the Concrete. Implementations – Example: stub code, slow code, optimized code

Bridge (cont. ) Client Abstraction Implementor Concrete Implementor. A Refined Abstraction Concrete Implementor. B

Bridge (cont. ) Client Abstraction Implementor Concrete Implementor. A Refined Abstraction Concrete Implementor. B

Design pattern space [from Vlissides]

Design pattern space [from Vlissides]