Naming convention when the method signature is the same? - naming-conventions

Hi when you have a method with same signature let's say.
void getErrorMessage(int errorCode){
}
void getErrorMessage(int domain){
}
I know I have to change the name or differentiate the parameter but what would be the best way to approach?
---------------------------Edited.
How about for constructor?
For example
public ErrorMessage(int errorCode){
}
public ErrorMessage(int domain){
}

You could make the method name explicit:
getErrorByErrorCode(int errorCode)
And
getErrorByDomain(int domain)

You can add a "ByFoo" to the end of the method, like: getErrorMessageByCode or getErrorMessageByDomain

The least dangerous and easiest-to-understand way to do this is:
public class ErrorCode {
private int intCode;
ErrorCode(int intCode) {
this.intCode = intCode;
}
int getIntegerCode() {
return intCode;
}
}
public class Domain {
private int domain;
Domain(int domain) {
this.domain = domain;
}
int getIntegerCode() {
return domain;
}
}
Message getErrorMessage(ErrorCode errorCode)
Message getErrorMessage(Domain domain)
Note the classes are immutable. You should probably also override equals. Use these classes everywhere you would have used the integer values.
Now it is impossible to mistake an error code for a domain anywhere in your code. If you mistake one for the other you will get a compiler error, and the compiler will choose the correct implementation of getErrorMessage. You extract the integer value from the object only when you need to perform integer operations on it.

Related

Best Practice for OOP function with multiple possible control flows

In my project, I have this special function that does needs to evaluate the following:
State -- represented by an enum -- and there are about 6 different states
Left Argument
Right Argument
Left and Right arguments are represented by strings, but their values can be the following:
"_" (a wildcard)
"1" (an integer string)
"abc" (a normal string)
So as you can see, to cover all every single possibility, there's about 2 * 3 * 6 = 36 different logics to evaluate and of course, using if-else in one giant function will not be feasible at all. I have encapsulated the above 3 input into an object that I'll pass to my function.
How would one try to use OOP to solve this. Would it make sense to have 6 different subclasses of the main State class with an evaluate() method, and then in their respective methods, I have if else statements to check:
if left & right arg are wildcards, do something
if left is number, right is string, do something else
Repeat for all the valid combinations in each State subclass
This feels like the right direction, but it also feels like theres alot of duplicate logic (for example check if both args are wildcards, or both strings etc.) for all 6 subclasses. Then my thought is to abstract it abit more and make another subclass:
For each state subclass, I have stateWithTwoWildCards, statewithTwoString etc.
But I feel like this is going way overboard and over-engineering and being "too" specific (I get that this technically adheres tightly to SOLID, especially SRP and OCP concepts). Any thoughts on this?
Possibly something like template method pattern can be useful in this case. I.e. you will encapsulate all the checking logic in the base State.evaluate method and create several methods which subclasses will override. Something along this lines:
class StateBase
def evaluate():
if(bothWildcards)
evalBothWildcards()
else if(bothStrings)
evalBothStrings()
else if ...
def evalBothWildcards():
...
def evalBothStrings():
...
Where evalBothWildcards, evalBothStrings, etc. will be overloaded in inheritors.
there's about 2 * 3 * 6 = 36 different logics to evaluate
We can apply divide and conquer technique.
you have 6 states. It is possible to use Chain of Responibility pattern here to choose appropriate state handler
when desired state handler is found, then we can apply desired function. The appropriate function can be considered as strategy. So it is a place where Strategy pattern can be applied.
we can separate strategies by appropriate states and put them in simple factory to get desired strategy by key.
This is what we will do. So let's see it more thoroughly.
Chain of responsibility pattern
If you have a lot if else statements, it is possible to use Chain of Responsibility pattern. As wiki says about Chain of Responsibility:
The chain-of-responsibility pattern is a behavioral design pattern
consisting of a source of command objects and a series of processing
objects. Each processing object contains logic that defines the
types of command objects that it can handle; the rest are passed to
the next processing object in the chain. A mechanism also exists for
adding new processing objects to the end of this chain
So let's dive in code. Let me show an example via C#.
So this is our Argument class which has Left and Right operands:
public class Arguments
{
public string Left { get; private set; }
public string Right { get; private set; }
public MyState MyState { get; private set; }
public MyKey MyKey => new MyKey(MyState, Left);
public Arguments(string left, string right, MyState myState)
{
Left = left;
Right = right;
MyState = myState;
}
}
And this is your 6 states:
public enum MyState
{
One, Two, Three, Four, Five, Six
}
This is start of Decorator pattern. This is an abstraction of StateHandler which defines behaviour to to set next handler:
public abstract class StateHandler
{
public abstract MyState State { get; }
private StateHandler _nextStateHandler;
public void SetSuccessor(StateHandler nextStateHandler)
{
_nextStateHandler = nextStateHandler;
}
public virtual IDifferentLogicStrategy Execute(Arguments arguments)
{
if (_nextStateHandler != null)
return _nextStateHandler.Execute(arguments);
return null;
}
}
and its concrete implementations of StateHandler:
public class OneStateHandler : StateHandler
{
public override MyState State => MyState.One;
public override IDifferentLogicStrategy Execute(Arguments arguments)
{
if (arguments.MyState == State)
return new StrategyStateFactory().GetInstanceByMyKey(arguments.MyKey);
return base.Execute(arguments);
}
}
public class TwoStateHandler : StateHandler
{
public override MyState State => MyState.Two;
public override IDifferentLogicStrategy Execute(Arguments arguments)
{
if (arguments.MyState == State)
return new StrategyStateFactory().GetInstanceByMyKey(arguments.MyKey);
return base.Execute(arguments);
}
}
and the third state handler looks like this:
public class ThreeStateHandler : StateHandler
{
public override MyState State => MyState.Three;
public override IDifferentLogicStrategy Execute(Arguments arguments)
{
if (arguments.MyState == State)
return new StrategyStateFactory().GetInstanceByMyKey(arguments.MyKey);
return base.Execute(arguments);
}
}
Strategy pattern
Let's pay attention to the following row of code:
return new StrategyStateFactory().GetInstanceByMyKey(arguments.MyKey);
The above code is an example of using Strategy pattern. We have different ways or strategies to handle
your cases. Let me show a code of strategies of evaluation of your expressions.
This is an abstraction of strategy:
public interface IDifferentLogicStrategy
{
string Evaluate(Arguments arguments);
}
And its concrete implementations:
public class StrategyWildCardStateOne : IDifferentLogicStrategy
{
public string Evaluate(Arguments arguments)
{
// your logic here to evaluate "_" (a wildcard)
return "StrategyWildCardStateOne";
}
}
public class StrategyIntegerStringStateOne : IDifferentLogicStrategy
{
public string Evaluate(Arguments arguments)
{
// your logic here to evaluate "1" (an integer string)
return "StrategyIntegerStringStateOne";
}
}
And the third strategy:
public class StrategyNormalStringStateOne : IDifferentLogicStrategy
{
public string Evaluate(Arguments arguments)
{
// your logic here to evaluate "abc" (a normal string)
return "StrategyNormalStringStateOne";
}
}
Simple factory
There is no pattern like simple factory. However, it is a place where we can get instances of strategies by key. So by doing this we avoided to use multiple if else statements to choose correct strategy.
So, we need a place where we can store strategies by state and argument value. At first, let's create MyKey struct. It will have help us to differentiate State and arguments:
public struct MyKey
{
public readonly MyState MyState { get; }
public readonly string ArgumentValue { get; } // your three cases: "_",
// an integer string, a normal string
public MyKey(MyState myState, string argumentValue)
{
MyState = myState;
ArgumentValue = argumentValue;
}
public override bool Equals([NotNullWhen(true)] object? obj)
{
return obj is MyKey mys
&& mys.MyState == MyState
&& mys.ArgumentValue == ArgumentValue;
}
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
hash = hash * 23 + MyState.GetHashCode();
hash = hash * 23 + ArgumentValue.GetHashCode();
return hash;
}
}
}
and then we can create a simple factory:
public class StrategyStateFactory
{
private Dictionary<MyKey, IDifferentLogicStrategy>
_differentLogicStrategyByStateAndValue =
new Dictionary<MyKey, IDifferentLogicStrategy>()
{
{ new MyKey(MyState.One, "_"), new StrategyWildCardStateOne() },
{ new MyKey(MyState.One, "intString"),
new StrategyIntegerStringStateOne() },
{ new MyKey(MyState.One, "normalString"),
new StrategyNormalStringStateOne() }
};
public IDifferentLogicStrategy GetInstanceByMyKey(MyKey myKey)
{
return _differentLogicStrategyByStateAndValue[myKey];
}
}
So we've written our strategies and we've stored these strategies in simple factory StrategyStateFactory.
Then we need to check the above implementation:
StateHandler chain = new OneStateHandler();
StateHandler secondStateHandler = new TwoStateHandler();
StateHandler thirdStateHandler = new ThreeStateHandler();
chain.SetSuccessor(secondStateHandler);
secondStateHandler.SetSuccessor(thirdStateHandler);
Arguments arguments = new Arguments("_", "_", MyState.One);
IDifferentLogicStrategy differentLogicStrategy = chain.Execute(arguments);
string evaluatedResult =
differentLogicStrategy.Evaluate(arguments); // output: "StrategyWildCardStateOne"
I believe I gave basic idea how it can be done.

SOLID - Violated Open-Closed principle

I have the following code snippet
class Vehicle{
public String brand;
public double price;
public int productionYear;
public String toString(String formatType) {
switch(formatType) {
case "JSON": // JSON formatting here
return jsonFormattedString;
break;
case "XML": // XML formatting here
return xmlFormattedString;
break;
default: // default formatting
return defaultFormattedString;
}
}
I believe that the problem with this approach is the need of changing
the source code if the behaviour changes (another formatting type);
and maybe other SOLID violations that I missed.
How can this be better implemented?
What I would do is introduce another class for "Exporting" your vehicle.
Something like this.
public class VehicleExporter
{
public string ExportAsJson(Vehicle vehicle)
{
// Do the JSON thing
}
public string ExportAsXML(Vehicle vehicle)
{
// Do the XML thing
}
}
The big thing with your design is not as much breaking the open closed principle, but the responsibility of the vehicle class.
When your class is doing the toString(), it is essentially trying to do something outside of it's responsibility.
Please let me know if I can clarify further.

Accesing arraylist property from another class using constructor

So i have a class that makes an array list for me and i need to access it in another class through a constructor but i don't know what to put into the constructor because all my methods in that class are just for manipulating that list. im either getting a null pointer exception or a out of bounds exception. ive tried just leaving the constructor empty but that dosent seem to help. thanks in advance. i would show you code but my professor is very strict on academic dishonesty so i cant sorry if that makes it hard.
You are confusing the main question, with a potential solution.
Main Question:
I have a class ArrayListOwnerClass with an enclosed arraylist property or field.
How should another class ArrayListFriendClass access that property.
Potential Solution:
Should I pass the arraylist from ArrayListOwnerClass to ArrayListFriendClass,
in the ArrayListFriendClass constructor ?
It depends on what the second class does with the arraylist.
Instead of passing the list thru the constructor, you may add functions to read or change, as public, the elements of the hidden internal arraylist.
Note: You did not specify a programming language. I'll use C#, altought Java, C++, or similar O.O.P. could be used, instead.
public class ArrayListOwnerClass
{
protected int F_Length;
protected ArrayList F_List;
public ArrayListOwnerClass(int ALength)
{
this.F_Length = ALength;
this.F_List = new ArrayList(ALength);
// ...
} // ArrayListOwnerClass(...)
public int Length()
{
return this.F_Length;
} // int Length(...)
public object getAt(int AIndex)
{
return this.F_List[AIndex];
} // object getAt(...)
public void setAt(int AIndex, object AValue)
{
this.F_List[AIndex] = AValue;
} // void setAt(...)
public void DoOtherStuff()
{
// ...
} // void DoOtherStuff(...)
// ...
} // class ArrayListOwnerClass
public class ArrayListFriendClass
{
public void UseArrayList(ArrayListOwnerClass AListOwner)
{
bool CanContinue =
(AListOwner != null) && (AListOwner.Length() > 0);
if (CanContinue)
{
int AItem = AListOwner.getAt(5);
DoSomethingWith(Item);
} // if (CanContinue)
} // void UseArrayList(...)
public void AlsoDoesOtherStuff()
{
// ...
} // void AlsoDoesOtherStuff(...)
// ...
} // class ArrayListFriendClass
Note, that I could use an indexed property.

Can I Use Ninject To Bind A Boolean Value To A Named Constructor Value

I have a constructor such as:
public AnalyticsController(ClassA classA, ClassB classB, bool isLiveEnvironment)
{
...
}
isLiveEnvironment is determined using a call to an existing static class such as:
MultiTenancyDetection.GetInstance().IsLive();
I would like to be able to make this call outside of the controller and inject the result into isLiveEnvironment. Is this possible? I can not see how this can be done.
You can accomplish this using WithConstructorArgument and using a callback:
kernel.Bind<AnalyticsController>()
.ToSelf()
.WithConstructorArgument("isLiveEnvironment", ctx => MultiTenancyDetection.GetInstance().IsLive() );
You can even achieve this more generally (but i would not really recommend binding such a generic type for such a specific use case):
IBindingRoot.Bind<bool>().ToMethod(x => MultiTenancyDetection.GetInstance().IsLive())
.When(x => x.Target.Name == "isLiveEnvironment");
Alternatively, if you need the same configuration value in several / a lot of classes, create an interface for it:
public interface IEnvironment
{
bool IsLive { get; }
}
internal class Environment : IEnvironment
{
public bool IsLive
{
get
{
return MultiTenancyDetection.GetInstance().IsLive();
}
}
}
IBindingRoot.Bind<IEnvironment>().To<Environment>();

ServiceStack implement magic token in deserializer

I want to implement a magic token for my ServiceStack-based API. Whenever any value matches this special token, I'd like to signal special actions in my application. The ideal place for this assignment to occur would be after SS had processed the wire format (JSV, JSON, SOAP, etc.) and before it mapped the value onto the a .NET type. At the moment, I'm wondering about the best way to start on something like this. Is it something I could wire up in Configure()? Is it something I'll have to override and inject? Any assistance or direction in this matter would be appreciated, ASAP.
I don't see this as a ServiceStack implementation question, but rather a matter of how you define your DTOs. Given this requirement, as I understand it, I'd go with something like this:
interface IOverridableDTO
{
Object overrideValue(Object value);
}
class BaseOverridableDTO : IOverridableDTO
{
bool doOverride {get(){return(//results of magic token check)};}
public Object overrideValue(Object value)
{ if {doOverride}
return(null); // or whatever the override needs to be
return(value);
}
}
class MyDTO : BaseOverridableDTO
{
// override the overrideValue() method, if necessary
private int myDTOProperty;
public int? MyDTOProperty {
get() {return overrideValue((Object)myDTOProperty)};
set(int value) {myDTOProperty = value;}
}
}
// use as follows:
void DoSomethingWithAnOverridableDTO(BaseOverridableDTO dtoObject)
{ ... }