3
I am maintaining an ADVPL project. In it, I have some source files. Among these sources, I have an information miner in the GEO1 file and a communicator of the information mined in the GEO3 file.
In the initial operation, the loads were low and first the entire extraction was done to communicate to the external system about these changes. It turns out that this initial load is higher than initially expected, so I’m refactoring the system to, during the extraction, run the upload.
If it was something in Java, which I have more usual, I would take a more functional approach, passing a Consumer to my extractor. It would be as if the following were the original code:
class Minerador {
public List<InformacaoMinerada> mineraInformacoes() {
List<InformacaoMinerada> info = new ArrayList<>();
while (temInformacaoMineravel()) {
info.add(minerarProximaInformacao());
}
return info;
}
private InformacaoMinerada minerarProximaInformacao() {
// código de mineração que posso desconhecer, lei de Deméter
...
return stuff;
}
}
class Comunicador {
public void enviaDados(List<InformacaoMinerada> informacoes) {
// detalhes internos do envio
}
}
class Principal {
public static void main() {
Minerador miner = getMiner();
Comunicador mercurio = getComunicador();
mercurio.enviaDados(miner.mineraInformacoes());
}
public static Minerador getMiner() {
// inicia o minerador corretamente
return miner;
}
public static Comunicador getComunicador() {
// inicia o minerador corretamente
return comunicador;
}
}
In the transformation, I would have the communicator notified that there is new information and, according to a Threshold, send the received information:
class Minerador {
public void mineraInformacoes(Consumer<InformacaoMinerada> consumidorInformacao) {
List<InformacaoMinerada> info = new ArrayList<>();
while (temInformacaoMineravel()) {
consumidorInformacao.accept(minerarProximaInformacao());
}
}
private InformacaoMinerada minerarProximaInformacao() {
// código de mineração que posso desconhecer, lei de Deméter
...
return stuff;
}
}
class Comunicador {
private List<InformacaoMinerada> informacoesBufferizadas;
private int threshold;
public void enviaDadosBufferizados() {
if (informacoesBufferizadas.size() > 0) {
enviaDados(informacoesBufferizadas);
informacoesBufferizadas.clear();
}
}
public void adicionaInformacao(InformacaoMinerada info) {
informacoesBufferizadas.add(info);
if (informacoesBufferizadas.size() >= threshold) {
enviaDadosBufferizados();
}
}
private void enviaDados(List<InformacaoMinerada> informacoes) {
// detalhes internos do envio, mesmo código da enviaDados antiga
}
}
class Principal {
public static void main() {
Minerador miner = getMiner();
Comunicador mercurio = getComunicador();
miner.mineraInformacoes(mercurio::adicionaInformacao);
// para eventual envio de dados residuais
mercurio.enviaDadosBufferizados();
}
public static Minerador getMiner() {
// inicia o minerador corretamente
return miner;
}
public static Comunicador getComunicador() {
// inicia o minerador corretamente
return comunicador;
}
}
There is something equivalent to this lambda function in ADVPL?