Giter Club home page Giter Club logo

patternlanguage's People

Contributors

andrealvesaraujo avatar deniscrispe avatar dependabot[bot] avatar diogosmendonca avatar ovvesley avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

patternlanguage's Issues

Padrão gerando dois alertas no lugar de um

No padrão abaixo são gerados dois alertas no lugar de um. O ideal seria marcar o método getInstance, não os modificadores e classe de retorno do método.

Padrão:

public class SomeSingleton {
    
    //Alert: getInstance method should return instance attribute
    public static SomeSingleton getInstance(){
 
        //not_exists
        return instance;
    }
 
}

Código:

public class MySingleton 
{
    private static MySingleton instance;
 
    private MySingleton(){
 
    }
 
    public static MySingleton getInstance(){
        if(instance == null)
            instance = new MySingleton();
        return null;
    }
}

Alerta gerado:

2020-10-26 10:34:17,571 INFO  - File: .\src\main\java\com\github\diogosmendonca\MySingleton.java
2020-10-26 10:34:17,571 INFO  - Alert Message: getInstance method should return instance attribute
2020-10-26 10:34:17,571 INFO  - Start: L: 16 C: 5
2020-10-26 10:34:17,571 INFO  - End: L: 16 C: 18

2020-10-26 10:34:17,571 INFO  - Alert Message: getInstance method should return instance attribute
2020-10-26 10:34:17,571 INFO  - Start: L: 16 C: 19
2020-10-26 10:34:17,572 INFO  - End: L: 16 C: 30

Localização de identificadores por prefixo, sufixo ou pacote

Em algumas situações pode ser muito útil localizar padrões de nomes por prefixo e sufixo. Por exemplo, na implementação das verificações para um Facade precisamos localizar um grupo de Classes de por um pacote ou sufixo, identificando uma camada da aplicação que precisa ter seu acesso restrito via Façade. Veja o exemplo abaixo:

Padrão pretendido:

public class SomeFacade{

    //Alert: a Business Object should be called in a Facade method.
    public static String anyMethod(){
        //not_exists
        return sufixBusinessObject.anyMethod();
    }

}

Código:

public class ControlFacade{
    
    public static String diciplineSpecificService(){
        return DiciplineBusinessObject.diciplineSpecificService();
    }

    public static String OtherSpecificService(){
        return OtherBusinessObject.otherSpecificService();
    }

}

Repare que os elementos que são chamados no facade tem todos um sufixo BusinessObject. Adicionalmente, eles estão incluídos todos no mesmo pacote, sendo possível localizá-los também se houver a possibilidade de identificar um pacote em um padrão.

Localização de padrões dentro do mais de dois níveis de blocos não funciona

O padrão de código abaixo não é encontrado quando está dentro de um switch.

Padrão:

public class SomeClass{
    public static void main(String[] args){
        //Alert: ControlFacade cannot be called from view package, call a command instead.
        ControlFacade.someMethod();
    }
}

Código:

package com.github.diogosmendonca.view;

import com.github.diogosmendonca.control.*;

public class Main{

    private static String output = null;

    public static void main(String[] args){
        String result = null;
        if(args != null && args.length > 0){
            switch(args[0]){
                case "studentSpecificCommand":
                    result = ControlFacade.studentSpecificService();
                    break;
                case "diciplineSpecificCommand":
                    result = ControlFacade.diciplineSpecificService();
                    break;
                default:
                    result = "Command not found";
                    break;
            }
        }else{
            result = "Command not found";
        }
        System.out.println(result);
        output = result;
    }

    public static String getOutput(){
        return output;
    }

}

Remoção da Repetição dos alertas no pré-processamento

Quando vamos utilizar o pré-processamento para gerar opções para um mesmo alerta acaba precisando repetir múltiplas vezes o comentário //Alert. Seria interessante ter uma forma de evitar isto. Veja o exemplo abaixo e a proposta de solução.

Exemplo do problema:

public class AnyClass{
    //#BEGIN
    //Alert: Do not declare specific Apps (AppA or AppB) use the App instead.
    AppA anyVariable;
    //#OR
    //Alert: Do not declare specific Apps (AppA or AppB) use the App instead.
    AppA anyVariable = null;
    //#OR
    //Alert: Do not declare specific Apps (AppA or AppB) use the App instead.
    AppA anyVariable = new AppA();
    //#OR
    //Alert: Do not declare specific Apps (AppA or AppB) use the App instead.
    AppB anyVariable;
    //#OR
    //Alert: Do not declare specific Apps (AppA or AppB) use the App instead.
    AppB anyVariable = null;
    //#OR
    //Alert: Do not declare specific Apps (AppA or AppB) use the App instead.
    AppB anyVariable = new AppB();
    //#END
}

Proposta de solução. Esta proposta eu testei e ela não funciona.

public class AnyClass{
    //Alert: Do not declare specific Apps (AppA or AppB) use the App instead.
    //#BEGIN
    AppA anyVariable;
    //#OR
    AppA anyVariable = null;
    //#OR
    AppA anyVariable = new AppA();
    //#OR
    AppB anyVariable;
    //#OR
    AppB anyVariable = null;
    //#OR
    AppB anyVariable = new AppB();
    //#END
}

Necessidade do AND no pré-processamento

Hoje temos no pré-processamento o operador //#OR que nos dá a semântica de qualquer padrão que seja encontrado é retornado na busca. Contudo, existem casos onde é necessária a semântica AND, ou seja, quando todos os casos são encontrados é retornado um alerta (ou quando pelo menos um passa não é retornado um alerta). Veja o exemplo abaixo.

Na construção do padrão Command temos um atributo que mapeia os comandos. Este atributo deve existir, mas existem diversas formas de inicializá-lo. Somente quando nenhuma das formas está presente é que temos um problema devendo gerar um alerta. A implementação com o operador //#OR não contempla este caso, pois gera um alerta quando qualquer um deles falha. A semântica correta aqui seria existir um operador //#AND que quando todos os padrões geram alertas temos um problema, quando pelo menos um não gera alerta está tudo ok.

//Alert: Create in the invoker an static attribute that maps strings to command for store the commands.
public class SomeInvoker{
    
    //#BEGIN 

    //not_exists
    private static Map<String, Command> someVariableName;

    //#AND

    //not_exists
    private static Map<String, Command> someVariableName = null;

    //#AND

    //not_exists
    private static Map<String, Command> someVariableName = new AnyClass<>();

    //#AND

    //not_exists
    private static Map<String, Command> someVariableName = new AnyClass<String, Command>();

    //#END

}

Verificação de declaração de métodos em interfaces não funciona.

Ao tentar verificar se uma determinada interface possui um método o padrão não é encontrado.
Padrão:

//Alert: Declare the method execute in command interface. 
public interface SomeCommand{
    //not_exists
    public String execute();
}

Código:

package com.github.diogosmendonca.view.commands;

public interface Command {
}

A chamada do método e atribuição existe, mas o alerta é gerado como se não existisse.

Problema muito parecido com issue #15, só que com o not_exists. A chamada do método e atribuição existe, mas o alerta é gerado como se não existisse. Na verdade o ideal é que fosse somente a chamada do método anyVar.execute(), mas como a atribuição está no código tentei facilitar para o padrão e incluí a atribuição. Se eu tirar os ifs, e todo o outro código da main e deixar somente o padrão ele acha, mas esta não é a situação real de uso.

Padrão:

public class AnyClass {
    //Alert: Use the commands map to get a command and execute it.
    public static void main(String[] args){
        //not_exists
        anyVar = anyOtherVar.execute();
    }
}

Padrão

package com.github.diogosmendonca.view;

import com.github.diogosmendonca.control.*;
import java.util.*;
import com.github.diogosmendonca.view.commands.*;

public class Main{

    private static String output = null;

    private static Map<String,Command> commands = new HashMap<>();

    static{
        commands.put("diciplineSpecificCommand", new DiciplineSpecificCommand());
        commands.put("studentSpecificCommand", new StudentSpecificCommand());
    }

    public static void main(String[] args){
        String result = null;
        if(args != null && args.length > 0){
            Command c = commands.get(args[0]);
            if(c != null)
                result = c.execute();
            else
                result = "Command not found";
        }else{
            result = "Command not found";
        }
        System.out.println(result);
        output = result;
    }

    public static String getOutput(){
        return output;
    }

}

Alerta gerado:

2020-11-04 11:50:58,518 INFO  - File: .\src\main\java\com\github\diogosmendonca\view\Main.java
2020-11-04 11:50:58,520 INFO  - Alert Message: Use the commands map to get a command and execute it.
2020-11-04 11:50:58,530 INFO  - Start: L: 18 C: 5
2020-11-04 11:50:58,553 INFO  - End: L: 18 C: 43

Modificadores conflitantes podem causar confusão ou bug

No código abaixo o alerta não é gerado, acredito eu por conflito entre os anotations @AlertIfNotStatic e @AnyModifier. Contudo, ao retirar o @AnyModifier o alerta é gerado. Se for este mesmo o motivo do alerta não estar sendo gerado (como foi colocado @AnyModifier então não faz sentido @AlertIfNotStatic), seria bom informar o usuário que modificadores conflitantes estão sendo usados. Como se fosse um warning de compilação. Se for bug mesmo corrigir.

Padrão

public class SomeSingleton {

    @AlertIfNotStatic("Instance attribute should be static") 
    @AnyModifier
    SomeSingleton instance;
    
}

Código

public class MySingleton 
{
    private static MySingleton instance;
 
    private MySingleton(){
 
    }
 
    public static MySingleton getInstance(){
        if(instance == null)
            instance = new MySingleton();
        return null;
    }
}

Problema com o not_exists no return

O seguinte padrão parece não estar funcionando corretamente. Todos os elementos do padrão existem, mas mesmo assim um alerta é retornada quando utilizado o not_exists.

Padrão:

public class SomeFacade{
   //Alert: a Business Object should be called in a Facade method.
    public static String diciplineSpecificService(){
        //not_exists
        return DiciplineBusinessObject.diciplineSpecificService();
    }
}

Código:

package  com.github.diogosmendonca.control;

public class ControlFacade{
    public static String diciplineSpecificService(){
        return DiciplineBusinessObject.diciplineSpecificService();
    }
}
2020-10-26 14:27:35,150 INFO  - File: .\src\main\java\com\github\diogosmendonca\control\ControlFacade.java
2020-10-26 14:27:35,151 INFO  - Alert Message: a Business Object should be called in a Facade method.
2020-10-26 14:27:35,155 INFO  - Start: L: 7 C: 5
2020-10-26 14:27:35,159 INFO  - End: L: 7 C: 18

2020-10-26 14:27:35,159 INFO  - Alert Message: a Business Object should be called in a Facade method.
2020-10-26 14:27:35,159 INFO  - Start: L: 7 C: 19
2020-10-26 14:27:35,159 INFO  - End: L: 7 C: 25 

Not_exists reportando em local errado

No padrão e código abaixo o alerta é gerado duas vezes. A primeira marca a classe, o que está correto. Já a segunda marca o método, o que está conceitualmente errado, visto que o alerta deveria ser gerado na classe e não faz sentido este tipo de alerta em um método.
Padrão:

//Alert: Create in facade studentSpecificService with the same name and signature from those it will expose. Make it call the business object.
public class SomeFacade{
  
    //not_exists
    public static String studentSpecificService(){
    }

}

Código:

package  com.github.diogosmendonca.control;

import com.github.diogosmendonca.control.*;

public class ControlFacade{

    public static String diciplineSpecificService(){
        return DiciplineBusinessObject.diciplineSpecificService();
    }

}

Alerta Gerado:


2020-10-27 14:35:24,189 INFO  - File: .\src\main\java\com\github\diogosmendonca\control\ControlFacade.java
2020-10-27 14:35:24,189 INFO  - Alert Message: Create in facade studentSpecificService with the same name and signature from those it will expose. Make it call the business object.
2020-10-27 14:35:24,200 INFO  - Start: L: 5 C: 1
2020-10-27 14:35:24,204 INFO  - End: L: 5 C: 7

2020-10-27 14:35:24,204 INFO  - Alert Message: Create in facade studentSpecificService with the same name and signature from those it will expose. Make it call the business object.
2020-10-27 14:35:24,204 INFO  - Start: L: 7 C: 5
2020-10-27 14:35:24,205 INFO  - End: L: 7 C: 18

Verificar se uma classe estende outra ou implementa uma interface

Hoje não há forma de verificar se uma classe estende outra ou implementa uma determinada interface. Acredito que a melhor forma de implementar seja com anotation. @ShouldExtend("AlgumaClasse") @ShouldImplements("AlgumaInterface").

Exemplo:

@ShouldImplements("Command", "This class should implement the command interface")
public class SomeCommand{
  
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.