Showing posts with label Beautiful Mind. Show all posts
Showing posts with label Beautiful Mind. Show all posts

Tuesday, July 19, 2011

AI and Thread Pool Code Example

Finally uploaded some examples of Breadth-first search, Depth-first search, Best-first search, Genetic Algorithm, Binary search tree, Backward and forward chaining code. Also, I tried to create simple thread pool because I found this pooling idea is very interesting and widely used.

Monday, July 11, 2011

Entity Object Locking

Object locking is required to avoid concurrency problem in an application. Generally speaking, there are two types of object locking: Pessimistic Locking and Optimistic Locking.

Pessimistic locking is a locking strategy where we prevent users from doing certain things. Here is an example of pessimistic locking:

User A performs update action on an entity object, then user A gets write lock on the being updated entity object. At almost concurrent time, user B performs update action on the same entity object, then user B's action is rejected since the entity object's write lock is being hold by user A.

JPA doesn't support this strategy because it has many disadvantages. It can make the application slower because certain action have to wait for entity object's lock to be released.

Optimistic locking is a locking strategy where we will use object comparison to decide whether a certain transaction will be committed or rolled back. Here is an example of optimistic locking:

When a user performs update action on an entity object, he/she will retrieve a copy of that entity object. Changes are made to the copy object, not the original. When the user is about to save it to database, application checks whether data have been updated since the user retrieved it. If no update has been made, the user gets entity object's write lock, then the data is committed. Otherwise, it is rejected.

JPA support this strategy. It is implemented by adding a column to the table for the entity to save a version number. Every time the row is updated, the version number is incremented. It is by comparing that version number the update action is committed or rejected.

Thursday, October 28, 2010

Insertion sort

Akhirnya sempat juga ngeblok di sela-sela ngoding iPhone ;)). Tak terasa sudah lama meninggalkan pulau Java. Sekarang ini sedang demam mempelajari kembali algoritma-algoritma yang sudah bertahun-tahun ditinggalkan. Sebagai permulaan sebaiknya mulai dari Insertion Sort. Berikut adalah implementasinya di Java:

public class Algoritma {

public static void main(String[] args) {
int[] input = new int[] {5, 2, 4, 6, 1, 3};
insertionSortIncrease(input);
System.out.println("\n");
insertionSortDecrease(input);
}

private static void insertionSortIncrease(int[] input) {
for (int j = 1; j < input.length; j++) {
int key = input[j];
int i = j - 1;
while (i >= 0 && input[i] > key) {
input[i + 1] = input[i];
i--;
}
input[i + 1] = key;
}
for (int i = 0; i < input.length; i++) {
System.out.print(input[i] + " ");
}
}

private static void insertionSortDecrease(int[] input) {
for (int j = 1; j < input.length; j++) {
int key = input[j];
int i = j - 1;
while (i >= 0 && input[i] < key) {
input[i + 1] = input[i];
i--;
}
input[i + 1] = key;
}
for (int i = 0; i < input.length; i++) {
System.out.print(input[i] + " ");
}
}

}

Monday, October 4, 2010

Pattern Builder and Factory

Builder and Factory are two different pattern, obviously. But sometimes I get confused because of their name. Both patterns act as object manager, they create object and hide the creation from user.

Factory is used to create object in an object family. Usually I pass a static number and the factory will go through if-else condition to decide what object to create.

Builder on the other hand, create an object based on some object characteristics. For example we have an xml file that holds object's state, and we want to create an object based on the file. We then pass the xml, then the Builder will create the object for us.

Sunday, November 1, 2009

Design Pattern in Brief (10)

Facade

Facade digunakan untuk menyembunyikan kompleksitas dan dependency terhadap subsystem. Jika tidak menggunakan facade client akan langsung berhubungan dengan subsystem sehingga terjadi tight couple seperti gambar berikut :



Namun dengan memanfaatkan facade maka antara client dan subsystem menjadi lebih loose coupling seperti gambar berikut :



Berikut adalah contoh untuk lebih memahami pattern facade : Misalkan kita memiliki tiga bean yaitu Address, Account, dan CreditCard. Kita ingin menyimpan data ketiganya tanpa client harus mengetahui ketiga bean tersebut. Di sinilah facade berperan. Berikut adalah gambar ketiga bean dan facade tersebut :





Berikut beberapa catatan penting tentang facade :
- Facade seharusnya tidak didesain untuk menyediakan fungsi tambahan
- Jangan pernah mengembalikan return value berupa komponen dalam subsystem kepada client. Sebagai contoh jangan pernah memiliki method seperti CreditCard getCreditCard() karena client akan mengetahui isi subsystem dan penggunaan facade menjadi tidak jelas.
- Penggunaan facade seharusnya untuk melakukan business service, bukan individual task.

Sunday, October 18, 2009

Design Pattern in Brief (9)

Chain of Responsibility

Pattern ini mirip dengan model layering dalam arsitektur software. Pattern ini menjelaskan bahwa antara object pengirim request dan object-object yang menangani request sebaiknya terpisah bahkan benar-benar tidak saling terkait (loosely coupling).

Jika ada lebih dari satu object yang bertugas menangani request, maka prosesnya dilakukan secara berurutan. Urutan tersebut membentuk sebuah rantai di mana setiap object mempunyai pointer yang merujuk ke chain selanjutnya.

Object pertama yang menerima request bisa memutuskan apakah akan menghandle request atau meneruskannya ke object selanjutnya. Request tersebut berjalan terus sampai dihandle oleh salah satu object atau request sampai di ujung rantai tanpa ada yang menghandlenya. Dengan kata lain, setelah melewati serangkaian rantai tersebut, request bisa saja tidak ada yang menghandlenya.

Berikut adalah karakteristik dari Chain of Responsibility :

- Sekumpulan request handler, dan urut-urutannya sehingga membentuk sebuah rantai dapat dilakukan secara dinamis saat runtime oleh klien.
- Klien bisa memiliki rantai request handler yang berbeda-beda tergantung jenis requestnya.
- Baik klien maupun masing-masing object request handler tidak perlu tahu object handler mana yang akhirnya menghandle request.
- Setelah melalui rantai request handler, request bisa saja tidak ada yang menghandlenya.

Untuk aplikasinya perhatikan contoh berikut :

Misal kita mempunyai sebuah purchase request.



Agar purchase request ini bisa dikirim maka harus melewati serangkaian pemeriksaan batas pembelian oleh 4 manajerial level.





Perhatikan diagram dan kode berikut :



Kita memiliki PRHandler sebagai parent dari keempat manajerial class request handler di atas. Berikut adalah codenya

package edu.mat.pattern.chain;

import edu.mat.pattern.request.PurchaseRequest;

public abstract class RequestHandler {

protected RequestHandler nextHandler;

public abstract boolean authorize(PurchaseRequest request);

public RequestHandler getNextHandler() {
return nextHandler;
}

public void setNextHandler(RequestHandler nextHandler) {
this.nextHandler = nextHandler;
}
}

package edu.mat.pattern.chain;

import edu.mat.pattern.request.PurchaseRequest;

public class BranchManager extends RequestHandler {

private static final int LIMIT = 25000;

@Override
public boolean authorize(PurchaseRequest request) {
// do authorization
if(request.getAmount() <= LIMIT) {
System.out.println("Authorized by branch manager...");
return true;
} else
return nextHandler.authorize(request);
}

}

package edu.mat.pattern.chain;

import edu.mat.pattern.request.PurchaseRequest;

public class PresidentCOO extends RequestHandler {

private static final int LIMIT = 400000;

@Override
public boolean authorize(PurchaseRequest request) {
// do authorization
if(request.getAmount() <= LIMIT) {
System.out.println("Authorized by president coo...");
return true;
} else
return nextHandler.authorize(request);
}

}

package edu.mat.pattern.chain;

import edu.mat.pattern.request.PurchaseRequest;

public class RegionalDirector extends RequestHandler {

private static final int LIMIT = 100000;

@Override
public boolean authorize(PurchaseRequest request) {
// do authorization
if(request.getAmount() <= LIMIT) {
System.out.println("Authorized by regional director...");
return true;
} else
return nextHandler.authorize(request);
}

}

package edu.mat.pattern.chain;

import edu.mat.pattern.request.PurchaseRequest;

public class VicePresident extends RequestHandler {

private static final int LIMIT = 200000;

@Override
public boolean authorize(PurchaseRequest request) {
// do authorization
if(request.getAmount() <= LIMIT) {
System.out.println("Authorized by vice president...");
return true;
}else
return nextHandler.authorize(request);
}

}

package edu.mat.pattern.request;

public class PurchaseRequest {

private String id;
private String description;
private double amount;

public PurchaseRequest(String id, String description, double amount) {
super();
this.id = id;
this.description = description;
this.amount = amount;
}

public String getId() {
return id;
}

public String getDescription() {
return description;
}

public double getAmount() {
return amount;
}

}

package edu.mat.pattern.main;

import edu.mat.pattern.chain.BranchManager;
import edu.mat.pattern.chain.PresidentCOO;
import edu.mat.pattern.chain.RegionalDirector;
import edu.mat.pattern.chain.VicePresident;
import edu.mat.pattern.request.PurchaseRequest;

public class Main {

public static void main(String args[]) {
BranchManager branchManager = new BranchManager();
PresidentCOO presidentCOO = new PresidentCOO();
RegionalDirector regionalDirector = new RegionalDirector();
VicePresident vicePresident = new VicePresident();

branchManager.setNextHandler(regionalDirector);
regionalDirector.setNextHandler(vicePresident);
vicePresident.setNextHandler(presidentCOO);
presidentCOO.setNextHandler(null);

PurchaseRequest request = new PurchaseRequest("one", "request one", 300000);
branchManager.authorize(request);
}
}

Jika dijalankan :

Authorized by president coo...

Saturday, October 17, 2009

Design Pattern in Brief (8)

Adapter

Adapter adalah salah satu pattern yang populer. Untuk memahami pattern ini perhatikan contoh berikut :

Kita ingin melakukan validasi terhadap alamat customer. Untuk keperluan ini kita telah memiliki sebuah bean Customer, sebuah interface untuk validasi IAddressValidator, dan sebuah class konkret yang implement interface tersebut USAddressValidator.



Karena customer tidak hanya dari US saja, kita ingin menambah validator untuk Kanada, misalnya. Misal untuk alamat Kanada kita telah mempunyai sebuah class lain, CAAddress, yang tidak sama interfacenya dengan USAddressValidator. Interface dalam hal ini bukan berarti java interface atau GUI, tapi yang dimaksud adalah bahwa jika kita menerapkan CAAddress dalam struktur desain kita, maka akan terlihat aneh menurut klien. Karena itu kita membuat sebuh class lagi CAAddressAdapter yang berisi reference ke CAAddress.




Struktur class di atas bisa dilihat dalam diagram berikut :

Wednesday, October 14, 2009

Design Pattern in Brief (7)

Decorator

Dalam pemrograman OOP kita pasti sudah terbiasa dengan pattern inheritance. Inheritance adalah salah satu dasar dari OOP. Decorator bisa dibilang kebalikan dari inheritance. Untuk lebih memahami pattern ini perhatikan contoh berikut :

Misal kita mempunyai struktur class untuk logger seperti gambar berikut :



Dan selanjutnya sesuai dengan bisnis proses yang ada, kita diharuskan untuk bisa menampilkan dan menyimpan log berupa struktur HTML dan text terenkripsi. Bagaimana kita melakukan ini? Pendekatan pertama kita adalah dengan melakukan inheritance terhadap ConsoleLogger dan FileLogger. Dengan demikian kita akan mendapatkan struktur class seperti gambar berikut :



Dengan diagram di atas kita akan mendapatkan struktur file yang kompleks. Kita akan mencoba mengatasinya dengan pattern Decorator. Decorator menyarankan agar kita menggunakan wrapper, bukan inheritance. Pada contoh di atas, Decorator yang akan kita buat harus juga implements interface yang sama dengan object yang akan kita buat wrappernya, dalam hal ini interface Logger. Saat klien berinteraksi dengan decorator, mereka berinteraksi dengan cara yang sama seperti berinteraksi dengan object yang dibut wrappernya. Berikut adalah diagram untuk decorator :



Terlihat dari diagram di atas bahwa HTMLLogger dan EncryptLogger override method log(String) dari class di atasnya. Di dalam masing2 method tersebut HTMLLogger membuat inputan yang di-log berbentuk html dan EncryptLogger mengenkripsi inputannya. Bagaimana selanjutnya cara menampilkan ke console atau ke file? Perhatikan bahwa LoggerDecorator mempunyai sebuah variabel logger bertipe Logger. Variabel ini bisa diisi dengan wrapper class yang sesuai, misal ConsoleLogger atau FileLogger.

Berikut adalah diagram akhir yang menggambarkan struktur class :


Sunday, October 11, 2009

Design Pattern in Brief (6)

Visitor

Untuk memahami visitor perhatikan contoh berikut : Misal kita memiliki list of order yang bisa kita kategorikan menjadi tiga yaitu California order, Non California order, dan Overseas order. Saat mengiterasi list tersebut, untuk masing-masing order kita ingin menjalankan sebuah method, misalkan accept(), namun method accept ini akan melakukan hal-hal yang berbeda tergantung jenis ordernya. Bagaimana kita melakukan hal ini? Inilah yang coba dipecahkan pattern visitor.

Untuk mengimplementasikannya kita akan membuat sebuah interface IOrder yang berisi sebuah method yang sama, accept(IVisitor visitor) yang akan dieksekusi lewat list. Selanjutnya kita membuat tiga class, masing-masing untuk order yang berbeda.

Untuk visitornya, kita membuat sebuah interface, IVisitor, yang memiliki tiga method visit() dengan parameter yang berbeda, masing-masing untuk tiap order. Kemudian kita akan mengimplementasikan IVisitor dalam sebuah class VisitorImpl yang akan mengimplementasikan masing-masing method visit() tersebut.

Kita bisa merangkum class-class yang terlibat dalam diagram berikut :







Dan berikut adalah codenya :

package edu.mat.pattern;

public interface IOrder {

public void accept(IVisitor visitor);
}

package edu.mat.pattern;

public class OrderCalifornia implements IOrder {

private String message;

@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}

public String getMessage() {
if(message == null)
message = "Order California";
return message;
}

public void setMessage(String message) {
this.message = message;
}

}

package edu.mat.pattern;

public class OrderNonCalifornia implements IOrder {

private String state;

@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}

public String getState() {
if(state == null)
state = "New York";
return state;
}

public void setState(String state) {
this.state = state;
}

}

package edu.mat.pattern;

public class OrderOverseas implements IOrder {

private String destinationCountry;

@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}

public String getDestinationCountry() {
if(destinationCountry == null)
destinationCountry = "Indonesia";
return destinationCountry;
}

public void setDestinationCountry(String destinationCountry) {
this.destinationCountry = destinationCountry;
}

}

package edu.mat.pattern;

public interface IVisitor {

public void visit(OrderCalifornia orderCalifornia);
public void visit(OrderNonCalifornia orderNonCalifornia);
public void visit(OrderOverseas orderOverseas);
}

package edu.mat.pattern;

public class VisitorImpl implements IVisitor {

@Override
public void visit(OrderCalifornia orderCalifornia) {
System.out.println(orderCalifornia.getMessage());
}

@Override
public void visit(OrderNonCalifornia orderNonCalifornia) {
System.out.println(orderNonCalifornia.getState());
}

@Override
public void visit(OrderOverseas orderOverseas) {
System.out.println(orderOverseas.getDestinationCountry());
}

}

package edu.mat.pattern;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Main {

public static void main(String[] args) {
IVisitor visitor = new VisitorImpl();
List orders = new ArrayList();
orders.add(new OrderCalifornia());
orders.add(new OrderNonCalifornia());
orders.add(new OrderOverseas());

Iterator iter = orders.iterator();
while(iter.hasNext()) {
iter.next().accept(visitor);
}
}
}

Monday, October 5, 2009

Design Pattern in Brief (5)

Flyweight

Setiap object mengandung informasi yang tersimpan dalam propertynya. Informasi tersebut bisa dibagi menjadi dua kategori yaitu informasi intrinsik dan ekstrinsik. Informasi intrinsik adalah informasi yang independen, yaitu informasi yang bersifat tetap atau konstan terhadap instance suatu class. Contohnya adalah informasi nama dan alamat perusahaan pada class kartu identitas pegawai. Informasi ekstrinsik adalah informasi yang bersifat berubah-ubah tergantung object tempat informasi tersebut berada. Hal ini berarti informasi tersebut "unique" untuk tiap instance dari class. Sebagai contoh, nama dan jabatan pegawai adalah "unique" untuk tiap pegawai.

Sekarang misalkan kita memiliki sebuah class employee yang bisa dibuat menjadi ribuan object dan di dalam class tersebut tersimpan informasi intrinsik dan ekstrinsik. Jika hal itu terjadi maka akan menimbulkan overhead pada memori karena menyimpan tiap informasi intrinsik yang sebetulnya sama bagi semua object employee tersebut. Untuk mengatasi hal inilah pattern flyweight dibuat.

Pattern flyweight menyarankan untuk memisah informasi intrinsik ke dalam object sendiri yang disebut object flyweight. Tiap object yang membutuhkan object flyweight dapat berbagi instance flyweight sehingga akan mampu menghemat memori dan waktu yang dibutuhkan untuk membuat object (object creation time).

Berikut adalah requirement yang harus dipenuhi untuk membuat flyweight :
- Hanya ada satu object flyweight dan object tersebut digunakan bersama oleh object lain yang membutuhkan.
- Object yang memanfaatkan flyweight di atas tidak boleh secara langsung membuat object flyweight.

Untuk memenuhi requirement di atas maka berikut adalah pendekatan yang dilakukan
- Class flyweight harus memiliki konstruktor private sehingga tidak bisa dibuat oleh class lain.
- Pattern singleton digunakan untuk memastikan bahwa tidak ada duplikasi object.

package edu.mat.pattern;

public interface IFlyweight {

public String getCompanyName();
public String getCompanyAddress();

}

package edu.mat.pattern;

import java.util.HashMap;
import java.util.Map;

public class FlyweightFactory {

private static final FlyweightFactory INSTANCE = new FlyweightFactory();
private Map flyweightList;

private FlyweightFactory() {
super();
this.flyweightList = new HashMap();
}

public static FlyweightFactory getInstance() {
return INSTANCE;
}

public synchronized Flyweight getFlyweight(String companyName) {
if(flyweightList.get(companyName) == null) {
Flyweight fly = new Flyweight(companyName);
flyweightList.put(companyName, fly);
return fly;
}
else
return flyweightList.get(companyName);
}

private class Flyweight implements IFlyweight {

private String companyName;
private String companyAddress;

private Flyweight(String companyName) {
super();
this.companyName = companyName;
if(companyName != null) {
if(companyName.equals("IBM"))
this.companyAddress = "California";
else if(companyName.equals("SUN"))
this.companyAddress = "Silicon Valley";
}
}

@Override
public String getCompanyAddress() {
return companyAddress;
}

@Override
public String getCompanyName() {
return companyName;
}

}

}

package edu.mat.pattern;

public class Main {

public static void main(String[] args) {
FlyweightFactory factory = FlyweightFactory.getInstance();
System.out.println(factory.getFlyweight("SUN"));
System.out.println(factory.getFlyweight("IBM"));
System.out.println(factory.getFlyweight("SUN"));
System.out.println(factory.getFlyweight("IBM"));
}
}

Saat dijalankan akan menghasilkan :

edu.mat.pattern.FlyweightFactory$Flyweight@42e816
edu.mat.pattern.FlyweightFactory$Flyweight@9304b1
edu.mat.pattern.FlyweightFactory$Flyweight@42e816
edu.mat.pattern.FlyweightFactory$Flyweight@9304b1

Perhatikan bahwa tepat hanya ada satu object flyweight untuk tiap companyName yang sama.

Sunday, October 4, 2009

Design Pattern in Brief (4)

Iterator

Iterator digunakan untuk mengakses isi sebuah container secara urut tanpa harus mengetahui isi container tersebut. Container yang dimaksud adalah collection of data. Di java, Iterator dapat diterapkan dengan implement java.util.Iterator. Ada dua macam iterator yaitu internal dan eksternal.

Misalkan kita memiliki sebuah container, maka internal iterator adalah iterator yang dimaintain oleh container tersebut. Container bertanggung jawab terhadap state dari iterator dan hanya bisa ada satu iterator dalam satu container. Sedangkan eksternal iterator adalah iterator yang diletakkan dalam object terpisah dari container. Jadi sekarang ada dua object, container dan iterator, di mana container mengembalikan sebuah object bertipe iterator dalam sebuah methodnya, misalnya getIterator().

Berikut adalah contoh internal iterator :
package edu.mat.pattern.iterator;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Vector;

/**
* Internal Iterator means the collection itself needs to maintain the iterator,
* that's why this collection extends Iterator. So this class can be viewed as both
* a container and an iterator.
* */
public class InternalIterator implements Iterator {

private Vector data;
private Enumeration enumeration;
private Employee nextEmployee;

public InternalIterator() {
data = new Vector();
data.add(new Employee("Santoso", "Los Angeles"));
data.add(new Employee("Rochmat", "New York"));

enumeration = data.elements();
}

@Override
public boolean hasNext() {
nextEmployee = null;
while(enumeration.hasMoreElements()) {
Employee employee = enumeration.nextElement();
nextEmployee = employee;
if(employee != null)
return true;
}
return false;
}

@Override
public Employee next() {
if(nextEmployee == null)
throw new NoSuchElementException();
else
return nextEmployee;
}

@Override
public void remove() {
// do nothing because we don't wanna remove anything

}

}

Dan berikut adalah contoh eksternal iterator yang terdiri dari container dan iterator :
package edu.mat.pattern.iterator;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;

public class ExternalContainer {

private Vector data;

public ExternalContainer() {
data = new Vector();
data.add(new Employee("Santoso", "Los Angeles"));
data.add(new Employee("Rochmat", "New York"));
}

public Enumeration getAllEmployees() {
return data.elements();
}

public Iterator getEmployeeByName(String name) {
return new ExternalIterator(this, name);
}

}

package edu.mat.pattern.iterator;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class ExternalIterator implements Iterator {

private String name;
private Enumeration enumeration;
private Employee nextEmployee;

public ExternalIterator(ExternalContainer employees, String name) {
this.name = name;
this.enumeration = employees.getAllEmployees();
}

@Override
public boolean hasNext() {
nextEmployee = null;
while(enumeration.hasMoreElements()) {
Employee employee = enumeration.nextElement();
nextEmployee = employee;
if(employee != null) {
if(name == null)
return true; // jika tidak ada filter maka return true
else {
if(employee.getName() != null) {
if(name.equals(employee.getName()))
return true; // jika ada filter dan curr employee name sama maka return true
// jika ada filter tapi curr employee name tdk sama maka continue
} // jika ada filter tapi curr employee name null maka continue
}
}
}
return false; // jika next employee = null maka return false
}

@Override
public Employee next() {
if(nextEmployee == null)
throw new NoSuchElementException();
else
return nextEmployee;
}

@Override
public void remove() {
// do nothing because we don't wanna remove anything

}

}

Thursday, September 17, 2009

Design Pattern in Brief (3)

Composite

Setiap komponen atau objek bisa dikelompokkan ke dalam salah satu dari dua kategori, individual komponen atau komposit komponen (yang terdiri dari individual komponen dan komposit komponen lain). Composite pattern digunakan untuk memodelkan sebuah interface sehingga kedua komponen tersebut bisa dilihat sebagai sebuah komponen yang sama dari sisi klien. Sederhananya, klien akan melihat dan bisa memperlakukan kedua komponen tersebut dengan cara yang sama.

Implementasi composite bisa dilihat pada tree, yang terdiri dari parent nodes dan leaves. Berikut ini kita mempunyai sebuah interface FileSystemComponent yang mempunyai method-method untuk megakses file komponen dan direktori komponen.



Method addComponent() pada class DirComponent digunakan untuk menambah file atau direktori baru di susunan file sistem tersebut. Sedangkan untuk mendapatkan ukuran dari file sistem yang ada, klien cukup memanggil getComponentSize(). Klien memperlakukan sama kedua file sistem tersebut, file dan direktori, untuk mendapatkan ukuran file sistem yang ada.

Design berikut adalah perbaikan dari design sebelumnya.



Kita bisa memanfaatkan interface atau abstract class dengan memindahkan semua method di DirComponent ke interface atau abstract tersebut. Karena class FileComponent tidak seharusnya memiliki method selain getComponentSize() maka FileComponent bisa throw exception jika method2 tersebut dipanggil dari dirinya. Sedangkan DirComponent harus mengoverride method2 tersebut.

public abstract class FileSystemComponent {
String name;
public FileSystemComponent(String cName) {
name = cName;
}
public void addComponent(FileSystemComponent component)
throws CompositeException {
throw new CompositeException(
"Invalid Operation. Not Supported");
}
public FileSystemComponent getComponent(int componentNum)
throws CompositeException {
throw new CompositeException(
"Invalid Operation. Not Supported");
}
public abstract long getComponentSize();
}

public class FileComponent extends FileSystemComponent {
private long size;
public FileComponent(String cName, long sz) {
super(cName);
size = sz;
}
public long getComponentSize() {
return size;
}
}

public class DirComponent extends FileSystemComponent {
Vector dirContents = new Vector();
//individual files/sub folders collection
public DirComponent(String cName) {
super(cName);
}
public void addComponent(FileSystemComponent fc)
throws CompositeException {
dirContents.add(fc);
}
public FileSystemComponent getComponent(int location)
throws CompositeException {
return (FileSystemComponent) dirContents.elementAt(
location);
}
public long getComponentSize() {
long sizeOfAllFiles = 0;
Enumeration e = dirContents.elements();
while (e.hasMoreElements()) {
FileSystemComponent component =
(FileSystemComponent) e.nextElement();
sizeOfAllFiles = sizeOfAllFiles +
(component.getComponentSize());
}
return sizeOfAllFiles;
}
}

Yang perlu diperhatikan adalah bahwa setiap kali kita menambah method baru, misal removeComponent() untuk DirComponent, maka kita juga harus menambahkannya di abstract atau interfacenya (dan FileComponent harus mengoverridenya). Kenapa? Karena kedua class child, FileComponent dan DirComponent, harus bisa dilihat dan diperlakukan sama oleh klien.

Saturday, September 12, 2009

Design Pattern in Brief (2)

Prototype

Prototype bisa dipandang sebagai salah satu alternatif dari Factory dan Abstract Factory. Untuk memahaminya bisa dilihat pada contoh-contoh berikut.



Design di atas bisa diimplementasikan dengan abstract factory seperti berikut :



Dengan prototype kita bisa mengimplementasikannya seperti :





public class HostingPlanKit {
private HostingPlan basicPlan;
private HostingPlan premiumPlan;
private HostingPlan premPlusPlan;
public HostingPlanKit(HostingPlan basic, HostingPlan premium,
HostingPlan premPlus) {
basicPlan = basic;
premiumPlan = premium;
premPlusPlan = premPlus;
}
public HostingPlan getBasicPlan() {
return (HostingPlan) basicPlan.clone();
}
public HostingPlan getPremiumPlan() {
return (HostingPlan) premiumPlan.clone();
}
public HostingPlan getPremPlusPlan() {
return (HostingPlan) premPlusPlan.clone();
}


public class HostingPlanManager {
public static HostingPlanKit getHostingPlanKit(
String platform) {
HostingPlan basicPlan = null;
HostingPlan premiumPlan = null;
HostingPlan premPlusPlan = null;
if (platform.equalsIgnoreCase("Win")) {
basicPlan = new WinBasic();
premiumPlan = new WinPremium();
premPlusPlan = new WinPremPlus();
}
if (platform.equalsIgnoreCase("Unix")) {
basicPlan = new UnixBasic();
premiumPlan = new UnixPremium();
premPlusPlan = new UnixPremPlus();
}
return new HostingPlanKit(basicPlan, premiumPlan,
premPlusPlan);
}
}

Monday, September 7, 2009

Design Pattern in Brief

Immutable

Immutable berarti tidak dapat diubah. Apanya yang tidak dapat diubah? Tentunya state dari suatu object, secara teknis, tentu nilai dari variabelnya. Dalam design pattern kita bisa membuat sebuah object menjadi immutable dengan cara
1. Semua instance variabel harus diset hanya dari konstruktor. Tidak ada method atau cara lain untuk mengeset nilai variabel selain dari konstruktor tsb. Dengan kata lain jadikan instance variabel private dan tanpa setter.
2. Agar class yang kita inginkan menjadi immutable tidak bisa di-extends, maka kita deklarasikan class tersebut sebagai final. Dengan demikian tidak ada cara untuk mengoverride method yang kita miliki.
3. Semua instance variabel harus dideklarasikan final sehingga hanya bisa diinisialisasi sekali, lewat konstruktor.
4. Jika sebuah method mempunyai return value berupa class dari object tersebut, maka sebaiknya ia tidak mengembalikan object yang sebenarnya melainkan copy atau clonenya.

Monitor

Menulis tentang monitor tentunya mengingatkan pada kuliah Sistem Operasi oleh Bapak Mochammad Husni :). Tak salah lagi, topik yang jadi hot thread pada kuliah itu adalah race condition, deadlock. Monitor adalah mekanisme yang digunakan untuk mengatasi deadlock sehingga hanya satu thread yang bisa mengakses sebuah method dalam satu waktu. Pada Java hal ini diatasi dengan mendeklarasikan sebuah method sebagai synchronized.

Factory



Factory dapat digambarkan sebagai sebuah class yang mengotomatisasi pembuatan sebuah object. Dalam diagram berikut kita memiliki sebuah parent class (bisa abstract, interface, atau konkret class) yang diextend oleh dua subclass. Sebuah class lain, yang bisa jadi bukan bagian dari aplikasi kita, ingin memanfaatkan class yang telah kita buat tersebut. Yang class lain tersebut ketahui hanyalah parent class saja. Mereka tidak tahu menahu struktur hirarki class kita. Sementara itu struktur yang kita buat adalah request harus didelegasikan ke masing-masing subclass yang bersesuaian. Bagaimana kita dapat menginstansiasi class-class yang berbeda dan mengembalikan return value dengan tipe yang sama adalah tugas Class Factory.

Pada gambar kita memiliki dua buah struktur factory. Pertama adalah sebuah interface sebagai contract dengan class lain. Kedua adalah Konkret class yang berisi factory method yang bertugas 'memilih' subclass mana yang harus diinstansiasi. Bagaimana cara factory method melakukan tugasnya? Sederhananya dengan if-then rules atau switch.

Singleton

Dalam design pattern, singleton berarti hanya ada satu instance. Bagaimana cara mendapatkan hanya satu instance selama aplikasi berjalan? Kita bisa melakukannya dengan meletakkan variabel dengan tipe class singleton sebagai global variabel, semua class yang membutuhkan object tersebut merefer ke variabel global yang dimaksud. Namun walaupun demikian, client masih tetap bisa membuat instance dari class tersebut bukan? Walaupun bukan sebagai global variabel.

Sebuah class yang bisa membuat dirinya sendiri hanya mempunyai satu instance disebut singleton class. Berikut adalah cara membuat class menjadi singleton
1. Buat constructornya private. Dengan demikian tidak ada cara class lain menginstansiasi class tersebut selain dirinya sendiri.
2. Di dalam class singleton tersebut buat public static method dengan nama getInstance().
3. Di dalam body method getInstance() buat instance yang hanya dibuat sekali pada saat pertama class di-invoke.

public class Singleton {
private static final Singleton INSTANCE = new Singleton();

// Private constructor prevents instantiation from other classes
private Singleton() {}

public static Singleton getInstance() {
return INSTANCE;
}
}

Pada code di atas, instance singleton dibuat hanya sekali yaitu saat class dipanggil. Namun cara ini memiliki kelemahan yaitu instance dibuat saat pertama class diinisialisasi, bukan saat dipanggil.

public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() {}

/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}

public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}


Code di atas adalah yang diusulkan oleh Bill Pugh. Instance benar-benar dibuat saat getInstance() dipanggil, bukan saat class diinisialisasi.
AbstractFactory

Untuk memahami AbstractFactory perhatikan gambar berikut



















public class LuxuryVehicleFactory extends VehicleFactory {
public Car getCar() {
return new LuxuryCar("L-C");
}
public SUV getSUV() {
return new LuxurySUV("L-S");
}
}

public class NonLuxuryVehicleFactory extends VehicleFactory {
public Car getCar() {
return new NonLuxuryCar("NL-C");
}
public SUV getSUV() {
return new NonLuxurySUV("NL-S");
}
}

public abstract class VehicleFactory {
public static final String LUXURY_VEHICLE = "Luxury";
public static final String NON_LUXURY_VEHICLE = "Non-Luxury";
public abstract Car getCar();
public abstract SUV getSUV();

public static VehicleFactory getVehicleFactory(String type) {
if (type.equals(VehicleFactory.LUXURY_VEHICLE))
return new LuxuryVehicleFactory();
if (type.equals(VehicleFactory.NON_LUXURY_VEHICLE))
return new NonLuxuryVehicleFactory();
return new LuxuryVehicleFactory();
}
}

Monday, May 11, 2009

Single Layer Perceptron

Neural Network

Neural Networks berdasarkan algoritma pembelajarannya bisa dikelompokkan menjadi dua kategori yaitu Feed-forward network (jaringan saraf umpan maju) dan Recurrent-feedback network (jaringan saraf umpan balik). Feed-forward network dicirikan dengan graf yang tidak memiliki loop sedangkan recurrent-forward network pada grafnya memiliki loop-loop koneksi balik. Berikut adalah diagram pengelompokan jaringan saraf atau neural network :



Single-layer Perceptron

Single-layer perceptron bisa dibilang merupakan salah satu teknik jaringan saraf tiruan yang paling sederhana. Jaringan ini hanya memiliki lapisan input dan lapisan output. Jaringan ini termasuk supervised learning, artinya metode pembelajarannya dilakukan melalui contoh-contoh. Jaringan akan ditraining dengan sekumpulan contoh-contoh yang diketahui input dan outputnya. Selama proses belajar tersebut jaringan akan menyesuaikan nilai bobotnya agar menghasilkan output yang diinginkan. Jaringan ini bisa digambarkan sebagai berikut :



Jaringan di atas mempunyai input sebanyak n (x1 sampai xn) dengan masing-masing input mempunyai bobot wn. Sebuah bias ditambahkan ke dalam jaringan dengan angka pembelajaran = 1. Output yang dihasilkan adalah Y. Karena metode ini adalah supervised learning maka ada threshold yang harus dilewati. Berikut adalah beberapa notasi dan fungsi yang perlu kita ketahui :

1. xi = input ke-i, b = bias, α = angka pembelajaran (0<α≤1), wi = bobot masing-masing input, ti = batas ambang / threshold dari input ke-i

2. Output yang dihasilkan adalah : Yin = Σwi.xi + α.b

3. Sedangkan output dalam bentuk biner (y) adalah 1 jika 1 ≤ Yin dan 0 jika Yin ≤ 0

4. Perubahan nilai bobot (w) dan bias (b) selama learning dinotasikan sebagai :


Sekarang kita akan mencobanya pada fungsi logika OR. Berikut adalah gambar tabel diagram OR



Selain diagram OR, kita perlu menginisialisasi bobot masing-masing input yaitu masing-masing bernilai 0. Kita juga menginisialisasi bias = 0. Dengan demikian kita mendapatkan : w1=0, w2=0, b=0.

Sekarang kita akan mulai melakukan iterasi pada jaringan ini. Dalam empat iterasi nilai bobot dan bias tidak berubah lagi dan jaringan menghasilkan output sesuai yang diharapkan.







Wednesday, April 29, 2009

Aspect Oriented Programming

Dalam membuat software, kita harus memikirkan banyak hal dalam satu waktu seperti proses bisnis, security, logging, persistence, multithreading, transaction, dll. Dari sekian banyak hal yang harus dipikirkan di atas, kita bisa mengelompokkannya menjadi dua kategori (dalam istilah AOP disebut concern). Kategori pertama adalah core concern, yaitu fungsi-fungsi utama sebuah software dibangun. Dalam hal ini tentu saja adalah proses bisnis. Kategori kedua adalah system-wide concern atau crosscutting concern, yaitu fungsi-fungsi yang tersebar di seluruh bagian software. Fungsi-fungsi ini bukan fungsi utama tetapi pendukung sistem, namun keberadaannya tetap diperlukan untuk memenuhi requirement software yang baik. Contohnya adalah security, pooling, logging, dan persistence.

OOP, seperti Java dan C++, telah terbukti sebagai metodologi yang baik untuk implementasi core concern, tapi tidak cukup baik untuk crosscutting concern. Ambil contoh logging. Dengan Java kita terbiasa menulis kode untuk logging bercampur dengan bisnis proses, misalnya untuk debugging. Jika kita ingin mengubah logging, maka kita harus melakukan perubahan di core concern, dalam hal ini class atau method untuk proses bisnis. Sebagai ilustrasi lihat gambar berikut ini yang memperlihatkan sebuah sistem yang terdiri dari beberapa concern menjadi satu, dalam AOP disebut tangled (awut-awutan).



Perhatikan ilustrasi lain berikut ini, Ramnivas Laddad menggambarkan beberapa concern dalam multidimensional-space sebagai berikut



Dari gambar terlihat bahwa sebuah software terdiri dari tiga concern yaitu persistence, logging, dan business logic. Namun dalam implementasinya ketiga concern tersebut tetap menjadi satu dimensi karena metodologi OOP mengharuskannya demikian. Gambar di atas jika diimplementasikan dalam code lebih kurang seperti ini

public class MyAllInOneClass {
public void superMethod() {

// lakukan autorisasi

// logging start business process
// lakukan proses bisnis
// logging end business process
}
public void save() {...}
public void load() {...}
}

Dari implementasi class di atas terlihat bahwa concern persistence berada dalam satu class dengan core concern, juga security dan logging concern berada dalam satu method dengan core concern.

AOP adalah metodologi yang memisahkan antara core concern dan crosscutting concern dengan memperkenalkan sebuah modul yang disebut aspect. Dengan AOP, kita mengimplementasikan crosscutting concern dalam aspect, tidak lagi dalam core concern. Dengan demikian kita tidak perlu mengkhawatirkan masalah crosscutting concern lagi pada saat awal kita membangun software. Kita bisa fokus membangun proses bisnis karena crosscutting concern tersebut bisa ditambahkan ke dalam sistem tanpa kita perlu mengubah core concern.

OOP telah sukses membuktikan diri sebagai metodologi yang tepat untuk memecahkan sistem yang kompleks menjadi sederhana dengan membaginya ke dalam class-class yang dikenal dengan istilah modularisasi. Dalam loosely coupling, OOP juga bisa diandalkan dengan memisahkan interface dan class-class implementasinya.

AOP tidak dimaksudkan untuk menggantikan OOP, sebaliknya, AOP akan menjadikan OOP semakin handal dalam membuat modularisasi melalui pemisahan concern. Dan walaupun pemisahan abstract dan implementasi dalam interface dan class berhasil untuk core concern, namun tidak untuk crosscutting concern. Perhatikan bahwa untuk setiap kita melakukan logging kita tetap harus memanggil API logger di setiap method yang mau logging. Artinya code untuk memanggil API logging akan tersebar di seluruh core concern yang membutuhkannya, yang seperti telah digambarkan di atas sebagai code tangling (awut-awutan). Dengan AOP, kita tidak perlu memanggil API untuk logging dari core concern. Dua gambar berikut adalah ilustrasi sebelum dan sesudah AOP digunakan. Perhatikan bahwa pada gambar pertama kita memanggil API logging sedangkan pada gambar kedua seluruh modul benar-benar terpisah.





AOP Methodology

Membangun sistem menggunakan AOP mirip dengan membangun sistem menggunakan metodologi lainnya : mengidentifikasi concern, mengimplementasikan concern, dan membentuk sistem akhir dengan menggabungkan concern-concern tersebut.

1. Aspectual Decomposition

Pada tahap ini kita melakukan decompose requirements untuk mengidentifikasi core concern dan crosscutting concern.

2. Concern Implementation

Pada tahap ini kita mengimplementasikan tiap concern secara independen. Perhatikan bahwa pada tahap ini masing-masing concern diimplementasikan pada modulnya sendiri, terpisah dengan modul lain. Dengan demikian kita bisa membuat modul per modul secara bertahap, tidak perlu memikirkan sekian banyak modul dalam satu waktu.

3. Aspectual Recomposition

Pada tahap ini kita membuat recomposition rules dengan membuat modularization unit atau aspect. Proses recomposition disebut juga weaving atau integrating, dan akan membentuk sistem akhir berdasarkan aspect tersebut.

Berikut ilustrasi yang digambarkan oleh Ramnivas Laddad :



Bagaimanakah weaver bekerja? Cara yang paling sederhana adalah melalui source-to-source translation. Source code untuk masing-masing modul dan aspect diproses untuk membentuk woven source code. Aspect compiler kemudian mengirimkan woven-source-code tersebut kepada compiler bahasa pemrograman yang dipakai untuk membentuk byte-code. Dengan pendekatan ini menggunakan Java, maka Java-based AOP implementation mengubah masing-masing source code pada tiap modul kedalam woven java source code kemudian java compiler mengubahnya menjadi byte code. Perhatikan bahwa weaver tidak akan mengubah original source code sama sekali.

Berikut adalah contoh untuk memperjelas bagaimana AOP diimplementasikan pada Java

1. Kita memiliki core logic sebagai berikut



2. Kita memiliki crosscutting concern berupa logging interface seperti berikut

public interface Logger {
public void log(String message);
}

3. Kita memiliki aspect berikut



3. Setelah proses weaving maka kita memiliki source code kira-kira seperti berikut

 

©2009 Stay the Same | by TNB