Professional Documents
Culture Documents
Sasaran
z Memperkenalkan dan menerapkan beberapa
pola desain GoF
z Menunjukkan prinsip-prinsip GRASP sebagai
generalisasi dari pola-pola desain lainnya
1
Adapter (GoF)
z Nama: Adapter
z Problem:
z Bagaimana menyatukan antarmuka-antarmuka
yang tidak compatible?
z Bagaimana menyediakan antarmuka yang stabil
pada komponen-komponen yang serupa dengan
antarmuka yang berbeda-beda?
z Solusi (Saran): Ubah antarmuka awal sebuah
komponen menjadi antarmuka lainnya
melalui objek adapter penengah
2
Penerapan Pola Adapter pada NextGen POS
«interface» Adapters use interfaces and
ITaxCalculatorAdapter polymorphism to add a level of
indirection to varying APIs in other
getTaxes( Sale ) : List of TaxLineItems components.
TaxMasterAdapter GoodAsGoldTaxPro
Adapter
«interface» «interface»
IAccountingAdapter ICreditAuthorizationService
Adapter
postReceivable( CreditPayment )
postSale( Sale ) requestApproval(CreditPayment,TerminalID, MerchantID)
... ...
«interface»
IInventoryAdapter
SAPAccountingAdapter GreatNorthernAccountingAdapter
...
Penggunaan Adapter
:Register : SAPAccountingAdapter
makePayment
...
SOAP over
HTTP
postSale( sale )
xxx «actor»
: SAPSystem
3
Prinsip GRASP sebagai Generalisasi
dari Pola-Pola Desain Lainnya
Pattern Overload!
4
Contoh: Adapter dan GRASP
Low coupling is a way to achieve protection at a Protected Variation GRASP
variation point. Mechanism Principles
GoF Design
Adapter Patterns
5
Model Domain parsial yang
Telah Diperbaharui
... Sale
1
... dateTime
…
... Contains
1
Contains
...
1..* 1..*
...
Sales Tax
LineItem LineItem
quantity description
percentage
amount
Factory
z Disebut juga Simple Factory atau Concrete Factory
z Bukan merupakan pola desain GoF, namun banyak
digunakan.
z Merupakan penyederhanaan pola GoF Abstract
Factory.
z Pola ini menjawab permasalahan berikut:
z Pada solusi pola Adapter sebelumnya, siapa yang
membuat adapter-adapter tersebut?
z Bagaimana menentukan kelas adapter yang akan dibuat
(seperti TaxMasterAdapter atau
GoodAsGoldTaxProAdapter)?
6
z Jika beberapa objek domain membuat objek
adapter tersebut, tanggung jawab objek domain
tersebut menjadi keluar dari logika aplikasi murni
dan masuk ke dalam hal-hal yang berkaitan dengan
hubungan ke komponen-komponen software
eksternal.
z Pola desain dasar lainnya yang digarisbawahi ini
pada kasus ini adalah:
Desain untuk mempertahankan pemisahan
perhatian/tugas (separation of concerns).
Æ memodularkan perhatian yang berbeda dalam
area-area yang berbeda, sehingga masing-masing
memiliki fungsi yang kohesif
7
z Objek Factory memiliki beberapa
keuntungan:
z Memisahkan tanggung jawab pembuatan objek-
objek yang kompleks pada objek pembantu yang
kohesif
z Menyembunyikan logika pembuatan objek yang
mungkin kompleks
z Memperkenankan penerapan strategi manajemen
memori yang meningkatkan kinerja, seperti object
caching atau object recyling
z Nama: Factory
z Problem: Siapa yang harus bertanggung jawab
membuat objek-objek ketika ada beberapa
pertimbangan khusus, seperti logika pembuatan
objek yang kompleks, keinginan memisahkan
tanggung jawab pembuatan objek agar mencapai
kohesi yang lebih baik, dll?
z Solusi (Saran): Buat sebuah objek Pure Fabrication
yang disebut Factory yang menangani pembuat
objek-objek tersebut.
8
Pola Factory
ServicesFactory note that the factory methods
return objects typed to an
accountingAdapter : IAccountingAdapter interface rather than a class, so
inventoryAdapter : IInventoryAdapter that the factory can return any
taxCalculatorAdapter : ITaxCalculatorAdapter implementation of the interface
getAccountingAdapter() : IAccountingAdapter
getInventoryAdapter() : IInventoryAdapter
getTaxCalculatorAdapter() : ITaxCalculatorAdapter
...
if ( taxCalculatorAdapter == null )
{
// a reflective or data-driven approach to finding the right class: read it from an
// external property
}
return taxCalculatorAdapter;
9
Singleton (GoF)
z ServicesFactory memunculkan masalah baru
dalam desain: Siapa yang membuat factory itu
sendiri, dan bagaimana mengaksesnya?
z Beberapa hal yang perlu diperhatikan:
1. Hanya ada satu instance factory yang dibutuhkan dalam
proses.
2. Metoda-metoda factory ini mungkin perlu dipanggil dari
berbagai tempat dalam kode sehingga membutuhkan
akses ke adapter-adapter untuk meminta layanan
eksternalnyaÆ masalah visibility: bagaimana
mendapatkan visibility pada sebuah instance tunggal
ServiceFactory?
10
Singleton
z Nama: Singleton
z Problem: Tepatnya hanya satu instance dari
sebuah kelas yang diperkenankan, yaitu
singleton. Objek-objek membutuhkan sebuah
titik akses global dan tunggal
z Solusi: Definisikan sebuah metoda static
pada kelas yang mengembalikan singleton
1
ServicesFactory
// static method
public static synchronized ServicesFactory getInstance()
{
if ( instance == null )
instance = new ServicesFactory()
return instance
}
11
z Contoh:
public class Register {
public void initialize() {
… melakukan beberapa pekerjaan …
12
z Eager initialization
public class ServicesFactory {
// eager initialization
private static ServicesFactory instance =
new ServicesFactory();
13
Pesan implisit getInstance dengan Pola
Singleton dinyatakan dalam UML dengan
Tanda ‘1’
1
:Register
:ServicesFactory
initialize
aa = getAccountingAdapter
create
create :Register
accountingAdapter =
getAccountingAdapter
create : SAPAccounting
Adapter
accountingAdapter:
:Register
SAPAccountingAdapter
makePayment
create(cashTendered) : Payment SOAP over
HTTP
postSale( sale )
xxx «actor»
: SAPSystem
14
Strategy (GoF)
z Masalah desain berikutnya yang akan
dipecahkan adalah menyediakan logika
penetapan harga (pricing) yang lebih
kompleks, seperti diskon dari toko selama
satu hari, diskon untuk senior citizen, dll.
z Stategi pricing (disebut juga aturan,
kebijakan, atau algoritma) untuk satu
transaksi penjualan dapat bervariasi.
z Bagaimana merancang algoritma pricing
yang bervariasi ini?
z Nama: Strategy
z Problem:
z Bagaimana mendesain algoritma atau kebijakan
yang bervariasi namun berhubungan?
z Bagaimana mendesain kemampuan perubahan
algoritma atau kebijakan ini?
z Solusi (Saran): Definisikan setiap
algoritma/kebijakan/strategi dalam satu kelas
terpisah, dengan interface yang sama.
15
Kelas-Kelas Pricing Strategy
«interface»
ISalePricingStrategy
{ {
return s.getPreDiscountTotal() * percentage pdt := s.getPreDiscountTotal()
} if ( pdt < threshold )
return pdt
else
return pdt - discount
}
16
Strategi dalam Kolaborasi
lineItems[ i ] : :PercentDiscount
s : Sale
SalesLineItem PricingStrategy
t = getTotal
{ t = pdt * percentage }
loop st = getSubtotal
t = getTotal( s )
Sale
«interface»
date 1 ISalePricingStrategy
...
pricingStrategy getTotal( Sale ) : Money
getTotal()
...
getTotal()
PercentDiscount AbsoluteDiscount
{
PricingStrategy OverThreshold
...
PricingStrategy
return pricingStrategy.getTotal( this ) percentage : float
discount : Money
} getTotal( Sale ) : Money threshold : Money
17
Membuat Objek Strategi
dengan Factory
z Ada beberapa algoritma atau strategi pricing
yang berbeda dan selalu berubah sepanjang
waktu.
z Masalah: Siapa yang membuat objek strategi
tersebut?
z Solusi: Gunakan pola Factory
ÆPricingStrategyFactory bertanggung jawab
membuat semua objek strategi yang
dibutuhkan aplikasi.
instance : PricingStrategyFactory
getInstance() : PricingStrategyFactory
getSalePricingStrategy() : ISalePricingStrategy
getSeniorPricingStrategy() : ISalePricingStrategy
...
{
String classN am e = System .getProperty( "salepricingstrategy.class.nam e" );
strategy = (ISalePricingStrategy) C lass.forNam e( classNam e ).new Instance();
return strategy;
}
18
Membuat Objek Strategi
1
:Register
:PricingStrategyFactory
makeNewSale
create :Sale
ps =
getSalePricingStrategy
create(percent) ps : PercentDiscount
PricingStrategy
19
z Untuk lebih jelasnya, strategi pricing yang dikenakan
pada penjualan berdasarkan tiga faktor:
z Perioda waktu (senin)
z Jenis pelanggan (senior)
z Produk barang tertentu yang dibeli (teh Sosro)
z Solusi masalah ini membutuhkan strategi
penyelesaian konflik.
z Biasanya toko menerapkan strategi penyelesaian
konflik “terbaik bagi pelanggan (harga terendah)”.
z Namun ini dapat saja berubah, misalkan pada
masa-masa kesulitan keuangan, toko dapat
menerapkan strategi penyelesaian konflik “harga
tertinggi”
z Nama: Composite
z Problem: Bagaimana memperlakukan
sekelompok struktur komposisi objek-objek
menggunakan cara yang sama (dengan
polimorfik) seperti objek non-komposit
(atomik)?
z Solusi: Definisikan kelas-kelas untuk objek-
objek komposit dan atomik sehingga
semuanya mengimplementasikan interface
yang sama
20
Pola Composite
{ All composites maintain a list of
... contained strategies. Therefore,
return pricingStrategy.getTotal( this ) define a common superclass
} CompositePricingStrategy that
defines this list (named strategies).
Sale
«interface» 1..*
date 1 ISalePricingStrategy
...
pricingStrategy getTotal( Sale ) : Money strategies
getTotal()
...
{ CompositeBestForCustomer CompositeBestForStore
return sale.getPreDiscountTotal() * PricingStrategy PricingStrategy
percentage
}
{
lowestTotal = INTEGER.MAX
for each ISalePricingStrategy strat in pricingStrategies
{
total := strat.getTotal( sale )
lowestTotal = min( total, lowestTotal )
}
return lowestTotal
}
t = getTotal
loop st = getSubtotal
t = getTotal( s )
21
Superkelas Abstrak, Metoda Abstrak,
dan Pewarisan dalam UML
UML notation: An abstract class is
shown with an italicized name Composite
PricingStrategy
abstract methods are also shown with
italics
add( ISalePricingStrategy )
getTotal( Sale ) : Money
CompositeBestForCustomer CompositeBestForStore
PricingStrategy PricingStrategy
22
z Desain yang diinginkan dimulai dengan membuat
objek Composite yang mengandung kebijakan
diskon toko saat ini, seperti:
PercentageDiscountPricingStrategy.
z Jika pada tahap selanjutnya, strategi pricing
lainnya diterapkan, tambahkan strategi tersebut
pada composite.
z Tiga titik dalam skenario di mana strategi pricing
dapat ditambahkan pada composite:
1. Diskon yang ditetapkan toko saat ini ditambahkan ketika
objek sale dibuat
2. Diskon berdasarkan jenis pelanggan ditambahkan ketika
jenis pelanggan dikomunikasikan pada POS
3. Diskon tipe produk ditambahkan ketika produk
dimasukkan dalam objek sale
m ake
N ew Sale
create :Sale
ps =
getSale
PricingStrategy
create
ps :C om positeBestForC ustom er
PricingStrategy
23
z Kasus kedua (diskon berdasarkan jenis
pelanggan) didasarkan pada use case berikut:
24
Membuat strategi pricing untuk
diskon berdasar pelanggan (1)
enterCustomerForDiscount( custID )
c = getCustomer( custID )
enterCustomerForDiscount( c : Customer )
ref Enter Customer
For Discount
by Factory and
by Expert
High Cohesion
1
:PricingStrategy ps :CompositeBestForCustomer
s :Sale
Factory PricingStrategy
enterCustomer
ForDiscount( c : Customer )
addCustomer Pass
PricingStrategy( s ) Aggregate
Object as
Parameter
c = getCustomer
by High Cohesion
ps = getPricing
by Expert
Strategy
pct =
getCustomer
Percentage( c )
25
Façade (GoF)
z Kebutuhan lain yang dipilih pada iterasi ini
adalah aturan bisnis yang pluggable.
z Pada titik-titik yang dapat diprediksi dalam
skenario seperti ketika makeNewSale atau
enterItem terjadi pada use case Process
Sale, atau ketika kasir mulai menarik
bayaran, perilaku NextGen POS harus dapat
dikustomisasi.
26
z Jika transaksi penjualan dibayar dengan gift
certificate, batalkan semua jenis pembayaran
uang kembalian kecuali untuk gift certificate
lainnya.
z Saat transaksi penjualan baru dibuat,
dimungkinkan penjualan itu untuk sumbangan.
Toko dapat memiliki aturan hanya
memperkenankan entri barang dengan harga
masing-masing kurang dari $250, dan hanya
memperkenankan entri item jika yang login
adalah “manager”
Pola Facade
z Nama: Facade
z Problem: Dibutuhkan sebuah antarmuka bersama
yang disatukan bagi sekumpulan implementasi atau
interface berbeda (seperti dalam suatu subsistem).
Ada coupling yang tidak diinginkan pada banyak hal
dalam subsistem tersebut, atau implementasi
subsistem tersebut dapat berubah. Apa yang harus
dilakukan?
z Solusi/saran: Definisikan titik kontak tunggal pada
subsistem tersebut, yaitu sebuah objek facade yang
membungkus subsistem itu.
Objek facade ini menyatakan sebuah interface yang
disatukan dan bertanggung jawab untuk
berkolaborasi dengan komponen-komponen
subsistem tersebut.
27
z Sebuah facade adalah objek front-end yang
merupakan titik masuk tunggal pada layanan-
layanan sebuah subsistem.
z Implementasi dan komponen-komponen
lainnya pada subsistem tersebut
disembunyikan dan tidak dapat dilihat oleh
komponen eksternal.
z Facade menyediakan Protected Variations
dari perubahan-perubahan dalam
implementasi sebuah subsistem.
28
public class Sale {
public void makeLineItem( ProductDescription desc, int quantity ) {
SalesLineItem sli = new SalesLineItem( desc, quantity );
// call to the Facade
if ( POSRuleEngineFacade.getInstance().isInvalid( sli, this ) )
return;
lineItems.add( sli );
}
// ...
} // end of class
POSRuleEngine
... ...
29
z Facade sering diakses via Singleton.
z Dengan desain ini, kompleksitas dan
implementasi bagaimana aturan akan
direpresentasikan dan dievaluasi
disembunyikan dalam subsistem rule engine
yang diakses melalui facade
POSRuleEngineFacade..
Observer/Publish-
Subscribe/Delegation Event Model
(GoF)
z Kebutuhan lain pada iterasi ini adalah
menambah kemampuan window GUI untuk
me-refresh tampilan total harga penjualan.
Goal: When the total of the sale
changes, refresh the display with
the new value
Sale
total
...
setTotal( newTotal )
...
30
z Prinsip Pemisahan Model-View menyatakan objek
model (objek-objek non-UI seperti Sale) tidak
seharusnya mengetahui objek-objek View atau
presentasi seperti window.
z Prinsip ini mendukung Low Coupling dari layer lain
ke layer presentasi (UI).
z Konsekuensinya: layer view atau presentasi dapat
diganti yang lain tanpa mempengaruhi objek-objek
non-UI.
z Dengan demikian, prinsip ini mendukung Protected
Variation berkaitan dengan UI yang dapat berubah.
z Untuk itu, pola Observer dapat digunakan.
Pola Observer
z Nama: Observer (Pengamat)
z Problem: Beberapa jenis objek pelanggan
(subscriber) yang berbeda berminat pada perubahan
keadaan atau event pada objek penerbit (publisher),
dan mau beraksi dengan cara sendiri yang unik
ketika penerbit membangkitkan event. Lebih lanjut,
penerbit ingin mempertahankan low coupling pada
pelanggan.
z Solusi/saran: definisikan sebuah interface pelanggan
(subscriber) atau pendengar(listener). Penerbit
secara dinamis dapat mendaftarkan pelanggan-
pelanggan yang berminat pada suatu event dan
memberitahukan mereka ketika event tersebut
terjadi.
31
Pola Observer
{ {
for each PropertyListener pl in propertyListeners propertyListeners.add( lis );
pl.onPropertyEvent( this, nam e, value ); }
}
Sale
javax.swing.JFram e propertyListeners
*
... «interface»
setTitle() PropertyListener
setVisible()
... onPropertyEvent( source, nam e, value )
{
if ( nam e.equals("sale.total") )
saleTextField.setText( value.toString() );
}
SaleFram e1
32
5. Catat bahwa Sale tidak mengetahui objek
SaleFrame1, melainkan hanya mengetahui
objek-objek yang mengimplementasikan
interface PropertyListener. Ini memperkecil
coupling Sale ke window Æ coupling hanya ke
interface, bukan ke kelas GUI.
6. Instance Sale merupakan penerbit (publisher)
dari property events. Ketika harga total berubah,
Sale memberitahukan setiap objek
PropertyListener yang terdaftar.
Pengamat SaleFrame1
berlangganan pada penerbit Sale
sf : SaleFrame1 propertyListeners :
s : Sale
List<PropertyListener>
initialize( s : Sale )
addPropertyListener( sf )
add( sf )
33
Sale mempublikasikan sebuah property
event pada semua pelanggannya
s :Sale propertylisteners[ i ] :
PropertyListener
setTotal( total )
publishPropertyEvent
( "sale.total", total )
setText( value.toString() )
34
Siapa observer, listener,
subscriber, dan publisher?
Sale
javax.swing.JFrame propertyListeners
*
... «interface»
setTitle() PropertyListener
setVisible()
... onPropertyEvent( source, name, value )
onAlarm Event( source, tim e ) onAlarm Event( source, tim e ) onAlarm Event( source, tim e )
... ... ...
{ {
{
display notification dialog check that all required processes
beep
box are executing norm ally
}
} }
35
Contoh implementasi
class PropertyEvent extends Event {
private Object sourceOfEvent;
private String propertyName;
private Object oldValue;
private Object newValue;
//...
}
//...
class Sale {
private void publishPropertyEvent(
String name, Object old, Object new ) {
PropertyEvent evt = new PropertyEvent(
this, "sale.total", old, new);
for each AlarmListener al in alarmListeners
al.onPropertyEvent( evt );
}
//...
}
36