İlk olarak bir önceki gönderi içerisinde tanımlanan müşteri-müşteri özellikleri mimarisinin sınıflarını oluşturacak olursak elimizde bir mevduatHesabı sınıfımız olsun.
public class SavingsAccount
{
protected Money balance;
protected Percentage interestRate;
...
public Money getBalance() {
return balance;
}
public synchronized Money deposit(Money deposit) {balance+= deposit;}
public synchronized Money withdraw(Money amount) {
Money newBalance = balance - amount;
if (newBalance >= 0) {
balance = newBalance;
}
}
public void accrueDailyInterest()
{
Money interest = InterestCalculator.calcDailyInterest((), getInterestRate());
deposit(interest);
}
...
}
Basit şekilde mevduatHesabı sınıfını tanımladıktan sonra işlem olarak faiz oranının hergün eklendiği düşünelim. Ancak bu durumda her bir müşteri için faiz oranının ayrı ayrı olmasının kontrol edilmesi sorunu ortaya çıkmaktadır. Daha önce bahsedildiği gibi bu sorun müşteriler için mevduatHesabıTipi sınıfının oluşturulmasıyla çözümlenir.
public class SavingsAccountType
{
protected Percentage interestRate;
...
public Percentage getInterestRate()
{
return interestRate;
}
public synchronized void setInterestRate(Percentage ir)
{
interestRate = ir;
}
...
}
Geriye yönelik olarak Müşteri sınıfındaki faiz oranını müşteriTipi sınıfından alındığını düşünürsek;
public class SavingsAccount
{
...
protected SavingsAccountType type;
...
public SavingsAccountType getType()
{
return type;
}
public void accrueDailyInterest()
{
Percentage interestRate= getType().getInterestRate();
Money interest = InterestRateCalculator.calcDailyInterest(getBalance(),interestRate);
deposit(interest);
}
...
}
Bu andan sonra birde KrediHesabı olduğunu düşünelim. KrediHesabı ile MevduatHesabı sınıflarının ortak bir Hesap sınıfından türediğini varsayarsak, süpersınıf olarak hesap sınıfını tanımlarız.
public class Account
{
protected PartyId ownerId;
protected Money balance;
protected AccountType type;
...
public String getTypeName() {
return type.getName();
}
...
}
public class AccountType
{
protected String name;
...
public String getName() { return name;}
...
}
Ancak tüm sınıflar için tüm alanlar birbirinin aynı olamayacağından herbir hesap için bir overwriting işlemi ile yeni metodlar ve tipler tanımlanması gerekmektedir. Bu durumda herbir özel durum için bir overwriting işlemi yapılması özellikle büyük verilerin olduğu durumlarda ve farklı tipte hesapların çoğaldığı uygulamalarda sorunlar çıkarmaktadır. Bu sebeple özelliklerin tutulması için bir özellik listesi tutulması ve özelliklerin ortak bir sınıftan oluşturulması daha doğru olacaktır. Bu sayede bu listenin elemanları için farklı özellikler tutulabilecektir.
class Account
{
protected PartyId ownerId;
protected Money balance;
protected Hashtable properties;
...
public Money getBalance()
{
return balance;
}
public Object getProperty(String name)
{
Object result= getFieldProperty(name);
if (result == null)
{
result= getListProperty(name);
}
return result;
}
protected Object getFieldProperty(String name)
{
if (name.equals("balance"))
{
return getBalance();
}
...
}
protected Object getListProperty(String name)
{
return properties.get(name);
}
public synchronized void setProperty(String name, Object value)
{
if (isFieldPropertyName(name))
{
setFieldProperty(name, value);
}
else
{
setListProperty(name, value);
}
}
protected void setFieldProperty(String name, Object value)
{
// no code for balance, but for other properties.
...
}
protected void setListProperty(String name, Object value)
{
properties.put(name, value);
}
...
}
Bu noktadan geriye dönüp baktığımızda ilk olarak özelleştirilmiş bir hesabı modelledikten sonra ardından abstraction ile hesapları modelledik ve ardından hesapların farklılıklarından yola çıkarak Tip-Nesne Desenini kullarak hesap tiplerini oluşturduk. Ardından farklı hesapların farklı özellikler içereceğini düşünerek özellikleri özellik listesi desenine uygun olarak listelerde tuttuk. Son olarak farklı özelliklere sahip olan hesaplar gibi aynı özelliklere sahip hesaplarında olabileceğini düşündüğümüzde özellikler içinde bir tip tanımının yapılması gerektiği ortaya çıkmıştır.
class PropertyType
{
protected String name;
protected Class type;
protected boolean isMandatory;
...
public String getName()
{
return name;
}
public boolean isSupertypeOf(Class type)
{
return type.isAssignableFrom(type);
}
public boolean isValidValue(Object value)
{
// check value, possibly delegate to a strategy
}
...
}
Tanımladığımız özellik listesi özelliklerin tutulduğu hesap tipi sınıfını etkileyeceğinden bu durumda hesap tipi sınıfı tekrardan yazıldığında;
class AccountType
{
protected String name;
protected Hashtable propertyTypes;
...
public boolean hasPropertyType(String name)
{
return propertyTypes.containsKey(name);
}
public boolean isValidProperty(String name, Class type, Object value)
{
if (!hasPropertyType(name))
{
return false;
}
PropertyType pt = getPropertyType(name);
return pt.isSupertypeOf(type) && pt.isValidValue(value);
}
...
}
Pazartesi günü bu modellerin bir tasarım içerisinde nasıl yer alacağını ve Anlamsal Web içerisinde nasıl Dinamik Nesne Modeli ile bir uygulama geliştirileceğini açıklayacağım.
Hiç yorum yok:
Yorum Gönder