JavaRush /Blogue Java /Random-PT /Estratégia de modelo (estratégia)

Estratégia de modelo (estratégia)

Publicado no grupo Random-PT
O padrão Strategy define uma família de algoritmos, encapsula cada um deles e garante que sejam intercambiáveis. Ele permite que algoritmos sejam modificados independentemente de seu uso no lado do cliente (esta definição foi retirada do livro “Head First. Design Patterns” de Eric Freeman e Elizabeth Robson). Esta definição parece um pouco confusa, por isso precisamos explicá- la com mais detalhes em linguagem normal . Comecemos pela religião :) Existem muitas religiões no mundo (confissões, movimentos, crenças, etc.). Como poderíamos descrever isso em código. Bem, por exemplo, poderíamos pegar a classe Religião e herdar dela outras religiões. Vamos abstrair as coisas desnecessárias e usar um método believe() na classe Religion.
public abstract class Religion {
    public void believe() {
        System.out.println("Я верю в Бога-творца этого мира");
    }
}
Todas as outras religiões podem ser herdadas desta classe. Se nos tivéssemos limitado ao Cristianismo e até mesmo ao Islão e ao Judaísmo, então não teria havido problemas.
public class Judaism extends Religion {
}
public class Islam extends Religion {
}
public class Christianity extends Religion {
}
Mas se pensarmos nas outras religiões que existem agora (ou que existiam antes, mas desapareceram), então surgirão problemas, pelo menos com os budistas. Você terá que substituir o método de crença deles.
public class Buddhism extends Religion {
    @Override
    public void believe() {
        System.out.println("Есть Бог or боги or нет, это не важно, главное достичь нирваны :)");
    };
}
E como existem muitas religiões e elas até acreditam no monstro do macarrão (Pastafarianismo), então em todas essas religiões você terá que redefinir o método de acreditar. Mas podemos fazer isso de forma diferente, mover este método para a interface Faith e implementar o método believe nela e implementar este método em cada classe (e implementá-lo em cada classe conforme desejarmos)? Mas então teremos duplicação de código, bem, pelo menos entre judeus e cristãos. Os muçulmanos de Deus podem escrever em árabe.
public interface Faith {
    public void believe();
}
public class Christianity implements Faith {
    @Override
    public void believe() {
        System.out.println("Я верю в Бога-творца этого мира");
    }
}
public class Judaism implements Faith {
    @Override
    public void believe() {
        System.out.println("Я верю в Бога-творца этого мира");
    }
}
Implementar o método padrão não ajudará muito aqui; existem tantas religiões que mesmo se você definir este método por padrão na interface do Faith, você terá que implementar este método à sua maneira em todas as religiões não-monoteístas, e repeti-lo em algum lugar. O que o padrão Strategy nos oferece neste caso: ele oferece a criação de classes de modelo prontas para a interface atual, que serão então substituídas no construtor de uma religião específica. Aqueles. definir e criar a mesma família de algoritmos mencionada no início da definição.
public interface Faith {
    public void believe();
}
public class AbrahamicReligion implements Faith {
    @Override
    public void believe() {
        System.out.println("Я верю в Бога-творца этого мира");
    }
}
public class BuddismReligion implements Faith {
    @Override
    public void believe() {
        System.out.println("Есть Бог or боги or нет, это не важно, главное достичь нирваны :)");
    }
}
public class JediismReligion implements Faith {
    @Override
    public void believe() {
        System.out.println("Да пребудет с вами Сила!");
    }
}
E em cada classe no construtor, substitua-as.
public abstract class Religion {
    Faith faith;
}
public class Judaism extends Religion{

    public Judaism() {
        this.faith = new AbrahamicReligion();
    }
}
public class Christianity extends Religion{

    public Christianity() {
        this.faith = new AbrahamicReligion();
    }
}
public class Buddhism extends Religion {

    public Buddhism() {
        this.faith = new BuddismReligion();
    }
}
Assim, caso você precise incluir outra religião em seu projeto, não será necessário redefinir o método de crença para todas as aulas ou partes de aulas. E você só precisará implementar a classe que falta (se já não houver) que implementa a interface Faith e adicionar esta classe no construtor da nova religião.
public class PastafarianismReligion implements Faith{

    @Override
    public void believe() {
        System.out.println("Кто съел мои макароны???");
    }
}
public class Pastafarianism extends Religion {

    public Pastafarianism() {
        this.faith = new PastafarianismReligion();
    }
}
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION