- Behavioral design pattern
- hLb object Gi internal state changes nq ZLb State pattern behavior alter allow K‡i|
Intent:
- hLb object Gi internal state changes nq ZLb State pattern behavior alter allow K‡i|
- State pattern use K‡i ‡Kvb object Gi internal state change Gi mv‡_ mv‡_ Dnvi behavior alter K‡i|
- Object mg~‡ni state-dependent behavior implement Kvix internal state swapping Gi gva¨‡g Bnv achieve Kiv hvq|
- GKwU object Gi mKj state based behavior mg~n dependent state subclass G defer nq|
- Bnv object method mg~‡n AwZwi³ case statements use alleviates(Dckg ) K‡i / Kgvq|
UML Diagram:
- wb‡¤œ State pattern Gi UML representation ‡`qv n‡jv-
- hvi role mg~n wb¤œiƒc:-
- Context Object Gi State ‡K State interface Gi instance Øviv represent Kiv nq|
- Client code GB interface Øviv interact K‡i|
- Interface Context Object Gi state dependent behavior define K‡i Ges State interface represent K‡i|
- ConcreteStateA I ConcreteStateB Context Gi lifetime Gi g‡a¨ specific states represent K‡i|
- Ges D³ state specific behavior implement K‡i|
Real life example:
·
GKwU vending
machine Gi inventory, deposited amount,
changing ability, item selection Gi Dci base
K‡i KwZcq state Av‡Q|
·
Customer
hLb currency deposite K‡i Ges item select K‡i ZLb vending machine
o
nq‡Zv not
changeable product deliver K‡i
o
bZzev changeable
product deliver K‡i
o
bZzev insufficient
currency Gi
Kvi‡b †Kvb product deliver K‡i bv
o
bZzev insufficient
stock Gi Kvi‡b †Kvb product deliver K‡i bv
·
myZivs †`L‡Z
cvw”Q vending machine different state G
Customer Gi mv‡_ different behave K‡i A_©vr wewfbœ state G vending machine Gi behave wewfbœ iKg nq
A_©vr Dnvi state change nIqvi mv‡_ mv‡_ Dnvi behavior I change
nq -
·
The State pattern Gi †ÿ‡ÎI wewfbœ state G GKwU object Gi behavior wewfbœ iKg nq A_©vr D³ object Gi state change nIqvi
mv‡_ mv‡_ Dnvi behavior I change nq.
Code Example:
- GB examine G Avgiv †`L‡ev wKfv‡e State pattern e¨envi K‡i order object Gi Rb¨ state behavior provide Kiv nq|
- g‡bKwi GKwU order Gi wZbwU state Av‡Q (1). New (2). Shipped (3). Canceled
- New order shipped/ cancelled n‡Z cv‡i|
- wKš‘ Shipped order cancelled wKsev cancelled order Shipped n‡Z cv‡i bv|
- wb‡¤œ State pattern implementation G involved class mg~‡ni diagram †`qv n‡jv-
- cÖ_‡g GKwU solution Create Kwi Ges Dnvi name w`B StatePattern. Then Dnv‡Z GKwU C# library project add Kwi Ges Dnvi name w`B StatePattern.Model
- Then Dnv‡Z GKwU interface add Kwi Ges Dnvi name w`B IOrderState Ges Dnvi definition wb¤§iƒct
namespace StatePattern.Model
{
public
interface IOrderState
{
bool
CanShip(Order order);
void
Ship(Order order);
bool
CanCancel(Order order);
void
Cancel(Order order);
}
}
- Then GKwU enumeration add Kwi Ges Dnvi name w`B OrderStatus Ges Bnvi definition wb¤§iƒct
(Note : enumeration use K‡i order Gi
current
state identify Kiv hv‡e)
namespace StatePattern.Model
{
public enum
OrderStatus
{
New = 0,
Shipped = 1,
Canceled = 2
}
}
- GLb Avgivv actual Order class create Ki‡ev| GRb¨ project G new class add Ki‡ev Ges Dnvi name n‡e Order Ges D³ class G wb‡¤œv³ code add Ki‡ev-
namespace StatePattern.Model
{
public class
Order
{
private
IOrderState _orderState;
public
Order(IOrderState baseState)
{
_orderState
= baseState;
}
public int Id
{ get; set; }
public string
Customer { get; set; }
public
DateTime OrderedDate { get; set; }
public
OrderStatus Status()
{
return
_orderState.Status;
}
public bool
CanCancel()
{
return _orderState.CanCancel(this);
}
public void
Cancel()
{
if
(CanCancel())
_orderState.Cancel(this);
}
public bool
CanShip()
{
return
_orderState.CanShip(this);
}
public void
Ship()
{
if
(CanShip())
_orderState.Ship(this);
}
Internal void
Change(IOrderState orderState)
{
_orderState
= orderState;
}
}
}
- The first state to be created is the canceled order state.
- Then Avgiv state class mg~n create Ki‡ev| cÖ_g state class hv Avgiv create Ki‡ev Zv n‡jv canceled order state
- hLb GKwU order canceled n‡e ZLb Dnvi shipment possible n‡e bv|
- Add a new class to the project named CanceledOrderState that implements the IOrderState interface with the code listing that follows:
- GRb¨ project G GKwU new class add Kwi Ges Dnvi name w`B CanceledOrderState. CanceledOrderState class wU IOrderState interface ‡K implement Ki‡e Ges Bnvi code listing wb¤§iƒc n‡e-
namespace StatePattern.Model
{
public class
OrderCanceledState : IOrderState
{
public bool
CanShip(Order order)
{
return
false;
}
public void
Ship(Order order)
{
throw new
NotImplementedException(
“You can’t
ship a canceled order!”);
}
public
OrderStatus Status
{
get
{ return OrderStatus.Canceled; }
}
public bool
CanCancel(Order order)
{
return
false;
}
public
void Cancel(Order order)
{
throw new
NotImplementedException(
“This order
is already cancelled!”);
}
}
}
- Next state n‡jv order shipped state
- GRb¨ Avgiv Av‡iKwU class create Ki‡ev Ges Dnvi name n‡e OrderShippedState. GB class wU I IOrderState interface Øviv implement n‡e. Bnvi code listing wb¤§iƒc n‡e-
namespace StatePattern.Model
{
public class
OrderShippedState : IOrderState
{
public bool
CanShip(Order order)
{
return
false;
}
public void
Ship(Order order)
{
throw
new NotImplementedException(“You can’t ship a shipped order!”);
}
public
OrderStatus Status
{
get
{ return OrderStatus.Shipped; }
}
public bool
CanCancel(Order Order)
{
return
false;
}
public void
Cancel(Order order)
{
throw
new NotImplementedException(“You can’t cancel a shipped order!”);
}
}
}
- Finally Avgiv last order state add Ki‡ev hvnv new order identify Ki‡e|
- GRb¨ project G new class Add Kwi Ges Dnvi name w`B OrderNewState. BnvI IOrderState interface ‡K implement Ki‡e Ges Bnvi code listing wb¤§iƒc n‡e-
namespace StatePattern.Model
{
public class
OrderNewState : IOrderState
{
public bool
CanShip(Order order)
{
return
true;
}
public
void Ship(Order order)
{
Order.Change(new
OrderShippedState());
}
public
OrderStatus Status
{
get
{ return OrderStatus.New; }
}
public bool
CanCancel(Order order)
{
return
true;
}
public void
Cancel(Order order)
{
order.Change(new
OrderCanceledState());
}
}
}
- Dc‡iv³ exercise ‡_‡K Avgiv †`L‡Z cvB GK GKwU state-dependent behavior GK GKwU subclasses G define K‡i separate Kiv n‡q‡Q|
- Gi d‡j cieZ©x‡Z new state introduce Ges separately state test easy nq
- By taking advantage of this pattern, you prevent monolithic methods that need to determine the state of the object before implementing behavior; this is typically done through a set of case of nested if-else blocks.
- State pattern Gi advantage wb‡q behavior implementing Gi c~‡e© object Gi state determine Gi Rb¨ monolithic(huge) methods writing prevent Kiv hvq|
- hLb †Kvb object state Gi Dci depend K‡i Dnvi behavior change Kiv nq ZLb State pattern LyeB DcKvix|
- hLb †Kvb class G AwZwi³ switch/case or if blocks e¨eüZ nq ZLb State pattern e¨envi K‡i Dnv‡K Lye mn‡RB refactor Kiv hvq|
কোন মন্তব্য নেই:
একটি মন্তব্য পোস্ট করুন