Best Way to Switch Behavior Based on Type

Best way to switch behavior based on type

There's another possibility. Use virtual dispatch:

class Widget
{
public virtual void GuiStuff() { }
}
class RedWidget : Widget
{
public override void GuiStuff()
{
//... red-specific GUI stuff
base.GuiStuff();
}
}
class BlueWidget : Widget
{
public override void GuiStuff()
{
//... blue-specific GUI stuff
base.GuiStuff();
}
}

Changing function behavior based on the given argument in Python

Remove the quotes so you compare variables, not strings.

And use is to tell if the variables refer to the same objects, since you can't compare numpy arrays with ==.

def plot(array): 

if array is X_arr:
bins = np.arange(0,int(np.amax(array)+1),1)
filename = 'hist_X.png'

elif array id Y_arr:
bins = np.arange(0,int(np.amax(array)+1),10)
filename = 'hist_Y.png'

-some plotting here-

plt.setp(axs, xticks=bins)

plt.savefig(filename)
plt.show()

However, this is very poor design, as it means this function can only be used with those two specific variables. You should design things more generally, such as passing another argument that indicates the plotting method.

C++ template method, changing the behavior based on the template class

You can specialize your template over different types. If you start with a base case:

template <class T>
void method(T value);

You can then declare different behavior for any specific value of T:

template <>
void method<int>(int value) {
// special behavior
}

And so forth. But since only the input type of your function is changing, you really don't need templates in this case! You can just overload your function with different argument types:

void method(int T);
void method(float T);
void method(void* T);

EDIT: Using template specialization to get the name of a type and use it in another function template:

template <class T>
std::string type_to_string();

template <>
std::string type_to_string<int>() {
return "int";
}

template <>
std::string type_to_string<float>() {
return "float";
}

template <class T>
some_other_function(T value) {
std::cout << value << " is a " << type_to_string<T>() << std::endl;
}

Of course, you can still do this without templates:

std::string type_to_string(int) {
return "int";
}

some_other_function(int value) {
std::cout << value << " is a " << type_to_string(value) << std::endl;
}

If you had to do some complex type-level computation, I'd suggest using templates. But here, I think you can accomplish what you want rather nicely without them. Either way, the idiomatic way (with or without templates) is to split your function into its different natural pieces.

Write a JavaScript function that changes behavior based on optional arguments

The way you are doing is it fine, but here's a few tips.

1) In ES6 you could have a default argument in case one is not supplied:

function foo(optionalArg = 'something cool') {
// have your function go about its business as usual
}

2) Same as above, except not using ES6:

function foo(optionalArg) {
if (optionalArg === undefined) {
optionalArg = 'something cool'
}
// have your function go about its business as usual
}

3) Check your argument against undefined to avoid false positives:

function foo(optionalArg) {
if (optionalArg !== undefined) {
// do something with the optionalArg
} else {
// do something different
}
}

4) Place the longer block in the else statement for optimal readability:

function foo(optionalArg) {
if (optionalArg !== undefined) {
// do something with the optionalArg
} else {
// do something different
// big
// huge
// grandiose
// epic
}
}

I hope that helps!

Changing method behaviour depending on subtype of 2 input parameters

So I found a way which work using Visitor pattern :

public interface ICardVisitor {
public Card visit(TrumpCard card);
public Card visit(ColoredCard card);
public void setSecondCard(ColoredCard card);
public void setSecondCard(TrumpCard card);
}

public class ComparisonVisitor implements ICardVisitor {
private TrumpCard trumpCard;
private ColoredCard coloredCard;
...
//contains comparison logic & instances of card subtypes
}

I also had to add an extra function (in addition to the classic accept(Visitor v) method) to my abstract Card class :

public abstract void setThisCardAsParameter(ICardVisitor v);

inside the concrete Card implementations :

public Card accept(ICardVisitor visitor) {
return visitor.visit(this);
}

public void setThisCardAsParameter(ICardVisitor v) {
v.setSecondCard(this);
}

This way the comparison class know each subtype for each card so he has access to all specific methods of a given child class.
The call is looking like this :

public static void main(String [] args) {
ICardVisitor cmp = new ComparisonVisitor();
Card c = new TrumpCard(1);
Card c2 = new ColoredCard(CardTypes.SPADES,1);
ICardVisitor cmp = new ComparisonVisitor();
c.setThisCardAsParameter(cmp);
Card winningCard = c2.accept(cmp);
}

If that design is bad or can be improved, please let me know it !

How can I modify a function's behavior based on if it is being assigned to a variable?

Of course, you definitely shouldn't be doing this, but since the OP is more interested if it could be done for curiosity sake, then here is a snippet of code that demonstrates this capability:

class SomeWeirdClass
{
private bool sortApplied = false;
private List<int> elements;

public IList<int> Elements
{
get
{
if(sortApplied)
{
elements.Sort();
sortApplied = false;
}

return elements;
}
}

public SomeWeirdClass(IEnumerable<int> elements)
{
this.elements = elements.ToList();
}

public SortedWeirdClass Sort()
{
sortApplied = true;

return new SortedWeirdClass(this);
}

public class SortedWeirdClass
{
SomeWeirdClass parent;

internal SortedWeirdClass(SomeWeirdClass parent)
{
this.parent = parent;
}

public static implicit operator SomeWeirdClass(SortedWeirdClass sorted)
{
sorted.parent.sortApplied = false;

var elementCopy = new int[sorted.parent.elements.Count];
sorted.parent.elements.CopyTo(elementCopy);

var result = new SomeWeirdClass(elementCopy);
result.Sort();

return result;
}
}
}

Now using it in a program:

static void Main(string[] args)
{
SomeWeirdClass original = new SomeWeirdClass(new[] { 5, 1, 4, 3, 2 });

Console.WriteLine("Original Data: ");
Console.WriteLine(string.Join(" ", original.Elements));

SomeWeirdClass copy = original.Sort();

Console.WriteLine("Original Data after Sort and Assignment: ");
Console.WriteLine(string.Join(" ", original.Elements));

Console.WriteLine("Sorted Copy:");
Console.WriteLine(string.Join(" ", copy.Elements));

original.Sort();

Console.WriteLine("Original Data after Sort without Assignment: ");
Console.WriteLine(string.Join(" ", original.Elements));
}

The program outputs:

Original Data:
5 1 4 3 2
Original Data after Sort and Assignment:
5 1 4 3 2
Sorted Copy:
1 2 3 4 5
Original Data after Sort without Assignment:
1 2 3 4 5

The hack here is that sorting actually creates a temporary class which wraps the original. Unless that result is implicitly cast to the original type via assignment, the sorting effects will be applied to the original dataset. If assignment is made, the sorting is cancelled, and a copy is made for the new variable.



Related Topics



Leave a reply



Submit