Skip to content

Instantly share code, notes, and snippets.

@SunilGudivada
Last active February 7, 2022 10:08
Show Gist options
  • Save SunilGudivada/7afe42412dfec5cc64cbc567ef3470c7 to your computer and use it in GitHub Desktop.
Save SunilGudivada/7afe42412dfec5cc64cbc567ef3470c7 to your computer and use it in GitHub Desktop.
Behavioral Design Pattern - Strategy
/**
Design Patterns:
|
|_ Behavioral Design Pattern
|
|_ Strategy Design Pattern
@docs https://sunilgudivada369.gitbook.io/coding-interview-prepartion/design-patterns/behavioral-design-pattern/strategy-design-pattern
**/
public class Animal {
private String name;
private double weight;
// Instead of using an interface in a traditional way
// we use an instance variable that is a subclass
// of the Flys interface.
// Animal doesn't care what flyingType does, it just
// knows the behavior is available to its subclasses
// This is known as Composition : Instead of inheriting
// an ability through inheritance the class is composed
// with Objects with the right ability
// Composition allows you to change the capabilities of
// objects at run time!
public Flys flyingType;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setWeight(double weight) {
if (weight < 0) {
System.out.println("Weight should be >0");
} else {
this.weight = weight;
}
}
public double getWeight() {
return this.weight;
}
/* BAD
* You don't want to add methods to the super class.
* You need to separate what is different between subclasses
* and the super class
public void fly(){
System.out.println("I'm flying");
}
*/
public String tryToFly() {
return flyingType.fly();
}
public void SetFlyingType(Flys newFlyingType) {
this.flyingType = newFlyingType;
}
}
public class Dog extends Animal{
public Dog(){
super();
SetFlyingType(new cantFly());
}
/* BAD
* You could override the fly method, but we are breaking
* the rule that we need to abstract what is different to
* the subclasses
*
public void fly(){
System.out.println("I can't fly");
}
*/
}
public class Bird extends Animal{
Bird(){
super();
// We set the Flys interface polymorphically
// This sets the behavior as a non-flying Animal
SetFlyingType(new itFlys());
}
}
// The interface is implemented by many other
// subclasses that allow for many types of flying
// without effecting Animal, or Flys.
// Classes that implement new Flys interface
// subclasses can allow other classes to use
// that code eliminating code duplication
// I'm decoupling : encapsulating the concept that varies
public interface Flys {
public String fly();
}
class cantFly implements Flys {
public String fly() {
return "It Can't fly high";
}
}
class itFlys implements Flys {
public String fly() {
return "It flies";
}
}
public static void main(String[] args) {
Animal puppy = new Dog();
Animal parrot = new Bird();
System.out.println("Puppy:: " + puppy.tryToFly());
System.out.println("Parrot:: "+parrot.tryToFly());
// This allows dynamic changes for flyingType
puppy.SetFlyingType(new itFlys());
System.out.println("Puppy new strategy:: " + puppy.tryToFly());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment