Zajęcia, rok akademicki 2011/2012, semestr 2
Projektowanie obiektowe oprogramowania
Wykład skierowany jest do przyszłych architektów i projektantów systemów
informatycznych oraz do wszystkich programistów zainteresowanych
udoskonaleniem swojego warsztatu. Celem wykładu jest zapoznanie
studentów z kanonem współczesnych narzędzi w zakresie projektowania
obiektowego oprogramowania.
Materiał wykładu obejmuje:
- język UML w zakresie wymaganym przez projekty analityczne
i techniczne
- przegląd katalogu refaktoryzacji
- przegląd katalogu wzorców projektowych (GoF) (m.in. Observer,
Builder, Bridge, State, Strategy, Facade, Adapter, Mediator, itd.)
- przegląd katalogu wzorców aplikacyjnych (wzorców architektonicznych)
(m.in. Event Aggregator, Model-View-Controller, Object-Relational Mapping, Dependency Injection,
Service Locator, Enterprise Service Bus, Single Sign-on, Mock Object, itd.)
- jakośc oprogramowania: testowanie, metryki
Celem pracowni jest praktyczny kontakt z materiałem z wykładu.
Wymagania
Wymagany ukończony kurs języka Java lub C# - wszystkie przykłady będą bazowały na języku C#,
a większość zadań studenci będą rozwiązywali w językach C# lub Java.
Organizacja pracy
Podczas wykładu omawiane są kolejne zagadnienia według programu. Podczas ćwiczeń studenci zgłaszają gotowość do
zaprezentowania rozwiązań wybranych przez siebie zadań, wypełniając wcześniej standardowe paski deklaracji.
Prowadzący sprawdza indywidualnie (lub grupowo dla niektórych zadań, według uznania prowadzącego) rozwiązania wybranych zadań. Obecność na ćwiczeniach jest w związku z tym nieobowiązkowa.
Podstawą zaliczenia jest liczba zgromadzonych punktów
Egzamin
Egzamin odbył się dnia 29 maja 2012 (wtorek) w godz. 14-16, czyli w normalnej porze wykładu, w sali 25.
Wyniki egzaminu (plus wpisy ocen do indeksów) zostały ogłoszone 5 czerwca 2012 (wtorek) w godz. 14-16 w sali 302.
Ranking
Ranking na 15.05.2012
Wykłady
- 2012.02.07
- Wykład organizacyjny
- Omówienie programu wykładu
- Omówienie literatury
- Wprowadzenie do języka UML
- Diagramy klas
- Diagramy obiektów
Zestaw 1 (do 21-02-2012)
- 2012.02.14
- Wprowadzenie do języka UML, cd..
- Diagramy stanów
- Diagramy aktywności
- Diagramy sekwencji
- Diagramy wdrożenia
- Unified Process
Notatki
Zestaw 2 (do 28-02-2012)
- 2012.02.21
- Analiza obiektowa
- Zbieranie wymagań: FURPS+, S.M.A.R.T.
- Przypadki użycia - notacja skrócona, pełna
- Model pojęciowy, techniki tworzenia ("lista kategorii", "metoda fraz rzeczownikowych")
- Diagramy wdrożenia
- Unified Process
Notatki
Zestaw 3 (do 06-03-2012)
- 2012.02.28
Notatki
Zestaw 4 (do 13-03-2012)
- 2012.03.06
- Wzorce podstawowe
- Wzorce kreacyjne
Notatki
Zestaw 5 (do 20-03-2012)
- 2012.03.13
Notatki
Zestaw 6 (do 27-03-2012)
- 2012.03.20
Notatki
Zestaw 7 (do 03-04-2012)
- 2012.03.27
Notatki
Zestaw 8 (do 17-04-2012)
- 2012.04.03
Notatki
Zestaw 9 (do 24-04-2012)
- 2012.04.17
Notatki
Zestaw A (do 08-05-2012)
- 2012.04.24
- Repository
- Model-View-Presenter
Notatki
Zestaw B (do 15-05-2012)
- 2012.05.02
Notatki
Zestaw C (do 22-05-2012)
- 2012.05.08
- Behavior-Driven Design, testowanie za pomocą ram typów zastępczych
- Design by Contract, Code Contracts
- UI Automation, White
Notatki
Zestaw D (ostatni) (do 22-05-2012)
- 2012.05.15
- Enterprise Single Sign-on - przegląd pojęć
- OpenID - demonstracja funkcjonalna
- WS-Federation - przykład implementacji
Notatki
- 2012.05.22
- Enterprise Service Bus - przegląd pojęć
- Przykład najprostszej implementacji w oparciu o podsystem kolejkowy
Notatki
Implementacje
EventAggregator
namespace Uwr.OOP.BehavioralPatterns.EventAggregator
{
public interface ISubscriber<T>
{
void Handle( T Notification );
}
public interface IEventAggregator
{
void AddSubscriber<T>( ISubscriber<T> Subscriber );
void RemoveSubscriber<T>( ISubscriber<T> Subscriber );
void Publish<T>( T Event );
}
public class EventAggregator : IEventAggregator
{
Dictionary<Type, List<object>> _subscribers = new Dictionary<Type, List<object>>();
#region IEventAggregator Members
public void AddSubscriber<T>( ISubscriber<T> Subscriber )
{
if ( !_subscribers.ContainsKey( typeof( T ) ) )
_subscribers.Add( typeof(T), new List<object>() );
_subscribers[typeof( T )].Add( Subscriber );
}
public void RemoveSubscriber<T>( ISubscriber<T> Subscriber )
{
if ( _subscribers.ContainsKey( typeof( T ) ) )
_subscribers[typeof( T )].Remove( Subscriber );
}
public void Publish<T>( T Event )
{
if ( _subscribers.ContainsKey( typeof( T ) ) )
foreach ( ISubscriber<T> subscriber in _subscribers[typeof( T )].OfType<ISubscriber<T>>() )
subscriber.Handle( Event );
}
#endregion
}
}
Memento
namespace UWr.OOP.BehavioralPatterns2.Memento.MementoStructural
{
public class Originator
{
public Originator()
{
}
public string State { get; set; }
public Memento CreateMemento()
{
Memento m = new Memento();
m.SetState( this.State );
return m;
}
public void RestoreMemento( Memento m )
{
this.State = m.GetState();
}
}
public class Memento
{
public string StateBackup { get; set;}
public Memento()
{
}
public string GetState()
{
return this.StateBackup;
}
public void SetState( string StateToSet )
{
this.StateBackup = StateToSet;
}
}
[TestFixture]
public class Caretaker
{
[Test]
public void TestMemento()
{
Originator o = new Originator();
o.State = "foo";
Assert.That( o.State == "foo" );
Memento m1 = o.CreateMemento();
o.State = "bar";
Assert.That( o.State == "bar" );
Memento m2 = o.CreateMemento();
o.State = "qux";
Assert.That( o.State == "qux" );
o.RestoreMemento( m2 );
Assert.That( o.State == "bar" );
o.RestoreMemento( m1 );
Assert.That( o.State == "foo" );
}
}
}
namespace UWr.OOP.BehavioralPatterns2.Memento.UndoRedo
{
public class Originator
{
Stack undoStates = new Stack();
Stack redoStates = new Stack();
public Originator()
{
}
private string _state;
public string State
{
get { return _state; }
set
{
undoStates.Push( CreateMemento( this.State, value ) );
redoStates.Clear();
_state = value;
}
}
public void Undo()
{
if ( undoStates.Count > 1 )
{
Memento state = undoStates.Pop();
redoStates.Push( state );
this._state = state.From;
}
}
public void Redo()
{
if ( redoStates.Count > 0 )
{
Memento state = redoStates.Pop();
undoStates.Push( state );
this._state = state.To;
}
}
public Memento CreateMemento( string From, string To )
{
Memento m = new Memento();
m.SetState( From, To );
return m;
}
}
public class Memento
{
public string From { get; set; }
public string To { get; set; }
public Memento()
{
}
public void SetState( string From, string To )
{
this.From = From;
this.To = To;
}
}
[TestFixture]
public class Client
{
[Test]
public void TestMemento()
{
Originator o = new Originator();
o.State = "foo";
Assert.That( o.State == "foo" );
o.State = "bar";
Assert.That( o.State == "bar" );
o.State = "qux";
Assert.That( o.State == "qux" );
o.Undo();
Assert.That( o.State == "bar" );
o.Undo();
Assert.That( o.State == "foo" );
o.Undo();
Assert.That( o.State == "foo" ); // nie za daleko
o.Redo();
Assert.That( o.State == "bar" );
o.Redo();
Assert.That( o.State == "qux" );
o.Redo();
Assert.That( o.State == "qux" ); // nie za daleko
// undo + zmiana stanu
o.Undo();
Assert.That( o.State == "bar" );
o.State = "baz";
o.Redo();
Assert.That( o.State == "baz" );
o.Undo();
Assert.That( o.State == "bar" );
}
}
}
Literatura podstawowa
- Wrycza, Marcinkowski, Wyrzykowski - Język UML 2.0 w modelowaniu systemów informatycznych
- Fowler - Refactoring: Improving the Design of Existing Code
- Gamma, Helm, Johnson, Vlissides: Design Patterns: Elements of Reusable Object-Oriented Software
- B.Martin, M.Martin. Programowanie zwinne: zasady, wzorce i praktyki zwinnego wytwarzania oprogramowania w C#.
- Larman - UML i wzorce projektowe. Analiza i projektowanie obiektowe oraz iteracyjny model wytwarzania aplikacji
- Fowler - Patterns of Enterprise Application Architecture
- Microsoft Patterns & Practices - Application Architecture Guide