patterncsharpMinor
Messages with status codes
Viewed 0 times
withcodesmessagesstatus
Problem
I need to refactor following class:
I am not sure if it's worth knowing that I am mapping entity to database table through Entity Framework.
One more problem that I have is that fields
```
public string Message
{
get
{
switch (this.StatusCode)
{
case 10:
case 12:
case 13:
case :
public class Message
{
public Guid ID { get; set; }
public string MessageIn { get; set; }
public string MessageOut { get; set; }
public int StatusCode { get; set; } //EDIT could be changed during message lifecycle
public bool IsDeletable
{
get
{
switch (this.StatusCode)
{
case 12:
case 13:
case 22:
case 120:
return true;
default:
return false;
}
}
}
public bool IsEditable
{
get
{
switch (this.StatusCode)
{
case 12:
case 13:
case 22:
case 120:
return true;
default:
return false;
}
}
}
public string Message
{
get
{
switch (this.StatusCode)
{
case 11:
case 110:
return this.MessageIn;
case 12:
case 13:
case 22:
case 120:
return this.MessageOut;
default:
return string.Empty;
}
}
}
}- I would like to remove the business rules
IsDeletableandIsEditable
- I would like to remove these
switchstatements at the same time
I am not sure if it's worth knowing that I am mapping entity to database table through Entity Framework.
One more problem that I have is that fields
MessageIn and MessageOut are dependent on StatusCode. One of them are always populated. I could create new property but still the switch case is there:```
public string Message
{
get
{
switch (this.StatusCode)
{
case 10:
case 12:
case 13:
case :
Solution
I would like to remove these switch statments in the same time
Key points
Edit
addressing the comments:
Edit
...
Take Away
[Flags]
public enum StatusCode{
codeX = 1,
codeY = 2,
codeZ = 4,
codeA = 8,
editable = codeX | codeZ,
deleteable = codeY | codeZ
}Key points
- Use the
Flagsattribute
- enum values are powers of 2 - NOT multiples of 2
- bit-wise AND, OR provides the magic!
Edit
addressing the comments:
public static class StatusCodes {
private Dictionary values;
private Dictionary keys;
static StatusCodes() {
values = new Dictionary {
{StatusCode.A, 10},
{StatusCode.B, 20},
// and so on
}
keys = new Dictionary {
{10, StatusCode.A},
{20, StatusCode.B},
}
}
public static int GetValue(StatusCode theStatusCodeKey) {} // don't forget error trapping!
public static StatusCode GetKey(int theIntValue) {} // ditto
public static bool Editable(StatusCode thisCode) {
return (StatusCode.editable & thisCode) == thisCode;
}
public static bool Editable(int thisValue) {
return Editable( GetKey(thisValue));
}
}- The definition of the codes is all in one place - that's SOLID (D = DRY, don't repeat yourself)
- The definitions are in its own class - that's SOLID (S = single responsibility)
editableanddeleteablecan be removed fromMessage- that's very SOLID (S = single responsibility)
- We know what all those integers mean - thats.. well, just good programming.
- The
StatusCodes are available anywhere and everywhere in the application - That's SOLID, an attribute of being DRY.
- I'm not sure what "status code values might not be fixed" in the comments means. Surely the set of status codes is finite.
Edit
- Define "editability" in StatusCodes
- Use above to express Message is editable
- Address issue of exposing
StatusCode.editable"as if it were a valid code"
- Adhere to Single Responsibility
- Adhere to DRY principle
...
public static class StatusCodes
{
private static Dictionary values;
private static Dictionary keys;
static StatusCodes() {
values = new Dictionary {
{StatusCode.A, 10},
{StatusCode.B, 20},
{StatusCode.C, 30},
{StatusCode.D, 40}
// and so on
};
keys = new Dictionary {
{10, StatusCode.A},
{20, StatusCode.B},
{30, StatusCode.C},
{40, StatusCode.D}
};
}
[Flags]
enum Fungability
{
Editable = StatusCode.A | StatusCode.B,
Deleteable = StatusCode.B | StatusCode.D
}
public static int GetValue( StatusCode theStatusCodeKey ) {
int retVal;
values.TryGetValue( theStatusCodeKey, out retVal );
return retVal;
} // don't forget error trapping!
public static StatusCode GetKey( int theIntValue ) {
StatusCode retVal;
keys.TryGetValue( theIntValue, out retVal );
return retVal;
} // ditto
public static bool Editable( StatusCode thisCode )
{
return ( (StatusCode)Fungability.Editable & thisCode ) == thisCode;
}
public static bool Editable( int thisValue )
{
return Editable( GetKey( thisValue ) );
}
}
public class Message
{
public StatusCode myStatus;
public Message( int statusCode = 20 ) { myStatus = StatusCodes.GetKey(statusCode); }
public Message( StatusCode statusCode = StatusCode.A ) { myStatus = statusCode; }
public bool Editable
{
get { return StatusCodes.Editable( myStatus ); }
}
public bool Deleteable
{
get { return StatusCodes.Deleteable( myStatus ); }
}
}Take Away
- Structure data in an OO way
- Expose the data adhering to the Single Responsibility principle
- You get DRY as a side effect
- Structure yields simplicity, coherence, clarity.
Editableis implemented with only one line of code!
Message.Editablewent from originally "calculating" if the status code was editable, to simply asking theStatusCode"are you editable?"
Code Snippets
[Flags]
public enum StatusCode{
codeX = 1,
codeY = 2,
codeZ = 4,
codeA = 8,
editable = codeX | codeZ,
deleteable = codeY | codeZ
}public static class StatusCodes {
private Dictionary<StatusCode, int> values;
private Dictionary<int,StatusCode> keys;
static StatusCodes() {
values = new Dictionary<StatusCode, string> {
{StatusCode.A, 10},
{StatusCode.B, 20},
// and so on
}
keys = new Dictionary<in, StatusCode> {
{10, StatusCode.A},
{20, StatusCode.B},
}
}
public static int GetValue(StatusCode theStatusCodeKey) {} // don't forget error trapping!
public static StatusCode GetKey(int theIntValue) {} // ditto
public static bool Editable(StatusCode thisCode) {
return (StatusCode.editable & thisCode) == thisCode;
}
public static bool Editable(int thisValue) {
return Editable( GetKey(thisValue));
}
}public static class StatusCodes
{
private static Dictionary<StatusCode, int> values;
private static Dictionary<int,StatusCode> keys;
static StatusCodes() {
values = new Dictionary<StatusCode, int> {
{StatusCode.A, 10},
{StatusCode.B, 20},
{StatusCode.C, 30},
{StatusCode.D, 40}
// and so on
};
keys = new Dictionary<int, StatusCode> {
{10, StatusCode.A},
{20, StatusCode.B},
{30, StatusCode.C},
{40, StatusCode.D}
};
}
[Flags]
enum Fungability
{
Editable = StatusCode.A | StatusCode.B,
Deleteable = StatusCode.B | StatusCode.D
}
public static int GetValue( StatusCode theStatusCodeKey ) {
int retVal;
values.TryGetValue( theStatusCodeKey, out retVal );
return retVal;
} // don't forget error trapping!
public static StatusCode GetKey( int theIntValue ) {
StatusCode retVal;
keys.TryGetValue( theIntValue, out retVal );
return retVal;
} // ditto
public static bool Editable( StatusCode thisCode )
{
return ( (StatusCode)Fungability.Editable & thisCode ) == thisCode;
}
public static bool Editable( int thisValue )
{
return Editable( GetKey( thisValue ) );
}
}
public class Message
{
public StatusCode myStatus;
public Message( int statusCode = 20 ) { myStatus = StatusCodes.GetKey(statusCode); }
public Message( StatusCode statusCode = StatusCode.A ) { myStatus = statusCode; }
public bool Editable
{
get { return StatusCodes.Editable( myStatus ); }
}
public bool Deleteable
{
get { return StatusCodes.Deleteable( myStatus ); }
}
}Context
StackExchange Code Review Q#29680, answer score: 4
Revisions (0)
No revisions yet.