vendredi 22 octobre 2021

Conditional parameter without using if-else?

I have a program that is working fine at the moment.

from abc import ABC, abstractmethod


class User():
    def __init__(self, transport_strategy):
        self.transport_strategy = transport_strategy
    def transport(self):
        self.transport_strategy.transport()

class TransportStrategy():
    @abstractmethod
    def transport(self):
        pass

class WalkStrategy(TransportStrategy):
    def transport(self):
        print("I walk")

class FlyStrategy(TransportStrategy):
    def transport(self):
        print("I fly")

if __name__ == "__main__":
    u1 = User(FlyStrategy())
    u1.transport()
    u2 = User(WalkStrategy())
    u2.transport()

Now I need to make it accept parameters in cli mode. e.g. python example.py --strategy=fly

I can code like this but it violates the purpose that I used strategy pattern at the start. I want to reduce the unnecessary if-else as much as possible.

if args.strategy == "fly":
    strategy = FlyStrategy()
elif args.strategy == "walk":
    strategy = WalkStrategy()

DESIGN PATTERNS - Parsing 4 different JSON files

I have a problem that I cannot figure out. I have 4 different JSON files for configurations. Some of these files require extra API calls whereas others don't for instance.

4 files

A B C D

A and B just require.

A.getConfigs()

B.getConfigs()

C however requires

C.getConfigs()

C.getCase()

D requires

D.getConfigs()

D.getHeader()

What kind of pattern/object should I use when I also want to be able to call individual methods for C and D?

I could very easily move the getCase and getHeader logic into the client code but then I realized I need to use this logic in multiple places in the application code. So what can I do now?

Can I override a method in Java to let in do nothing?

I have some code to refactor, this is how it looks right now:

   class A {
        public void foo() {
            //do A

            //perform validation

            //do B
        }
    }

I need to implement a new method bar that does exactly what foo does, and skip the validation step:

    public void bar() {
        //do A

        //do B
    }

In order to reuse the code block "do A" and "do B", this is now I did. I created a protected method in class A, and moved the validation logic into this method:

   class A {
        public void foo() {
            //do A

            validate();

            //do B
        }


        protected void validate() {
            // perform validation
        }
    }

Then I created another class B that extends class A. It overrides the validate method and do nothing instead.

    class B extends A {
        @Override
        protected void validate() {
            //do nothing
        }
    }

However, I'm still not sure if this is a clean and elegant code design. Please let me know if there's anyway I can improve it. Thanks!

How could I call an abstract class method who is common between subclasses without instanciating any subclass

I have a code like this :

interface Contract {
  createSomething(); //not common
  updateSomething(); //not common
  getSomething(); //method who is supposed to be common between all strategies
}
interface Strategy {
  createSomething();
  updateSomething();
  getSomething();
}
Abstract class AbstractStrategy implements Strategy {

  @Override
  getSomething() {
    // the common code
  }
}
class strategyA extends AbstractStrategy {

  @Override
  createSomething() {...}

  @Override
  updateSomething() {...}
}
class ContractImpl implements Contract {

  @Override
  createSomething() {
    //get the good strategy 
    //call the strategy.createSomething();
  }

  @Override
  updateSomething() {
    //get the good strategy 
    //call the strategy.updateSomething();
  }

  @Override
  getSomething() {
     **Here is the question**
  }
}

Question:

  • How could I rewrite this code so I could call the getSomething() method without having to instanciate a random subclass just to call it with the super keyword ?

Rest API design with resource and deep resource

While designing an API which will have a resource and a deep resource (/resource/{id}/deepResource), Is it a good design to have the deepResource as a parameter in resource path when there are numerous dynamic deepResources?

For example: A post request to create a new resource under a section of main resource

POST: /accounts/{id}/{section}

{section} can be any deep resource under account like "comment", "service request", "checkbook request" etc.

The idea is {section} can grow as the application grows. So instead of having multiple endpoints for each deep resource like /accounts/{id}/comment

/accounts/{id}/service

/accounts/{id}/checks

how about having /accounts/{id}/{section}?

Logic on the backend is handled accordingly for each deep resource that gets added in future.

Appreciate your insights.

Is useMemo usefull rendering a prop value?

What's the difference between those two patterns ? Is the useMemo usefull ?

Will the number of rerenders change ?

1 - Just rendering a modified prop

const Component = ({ myObject }) => {
  const computedValue = changeMyValueWithSomeCalculus(myObject.value)
  return (
    <div>
       {computedValue}
    </div>
  )
};

2 - Using useMemo

const Component = ({ myObject }) => {
  const computedValue = useMemo(() => {
    return changeMyValueWithSomeCalculus(myObject.value);
  }, [myObject.value]);

  return (
    <div>
       {computedValue}
    </div>
  )
};

I've ran into this SO question very instructive but doesn't help me out with this choice !

Should controller take "id" as PathVariable or should it take "page-id"

We are trying to create SEO friendly roads. In this context, we decided to make changes to the url. E.g: /141(id) --> /example-page-141

I argue that we should get the "id" value as PathVariable on the back-end side. Another solution is to take "/example-page-141" as @PathVariable and find 141 in it. Which is the right solution?

  1. Solution

      @GetMapping("/get/{id}")
    public ResponseEntity<?> getProductDetail(@PathVariable Long id) 
    
        Product product = productService.getProductDetail(id);
    
        return new ResponseEntity<>(product, HttpStatus.OK);
    }
    
  2. Solution

     @GetMapping("/get/{id}")
     public ResponseEntity<?> getProductDetail(@PathVariable String id) {
    
    String[] bits = id.split("-");
    
    Long idLong = Long.valueOf(bits[bits.length-1]);
    
    Product product = productService.getProductDetail(idLong);
    
    return new ResponseEntity<>(product, HttpStatus.OK);
     }
    

Which should do the split operation on the front-end or the back-end?