tópicos grandes Java Avançado (C) os princípios de arquitetura de software de design (sob)

prefácio

A segunda lição começamos o tema de hoje, o próximo capítulo para continuar compartilhando serão introduzidos princípios de projeto de arquitetura de software: o princípio de interface de segregação, o princípio da Demeter, princípio da substituição Richter e princípios de multiplexação sintéticos. Este capítulo livros de referência "Primavera princípios 5 core" no primeiro capítulo órgãos internos Primavera Coração (nenhum equipamento eletrônico, combinada com a sua essência é o meu próprio entendimento, uma palavra uma palavra para derrubá-los da mão).

Interface Princípio Segregação

princípio interface de segregação (Interface de Segregação Principke, ISP) refere-se à utilização de uma pluralidade de interfaces dedicadas, interfaces sem utilizar o único geral, o cliente não deve contar com ele não faz interface. Sabemos que este princípio deve observar o seguinte ao projetar a interface:

(1) uma dependente de uma outra classe de interface classe deve basear-se num mínimo.

(2) estabelecer uma única interface, não criam interface de inchado.

(3) de interface possível processo de refinamento para minimizar de interface (não melhor, deve ser apropriado).

princípio da segregação de interface em linha com o que costumamos dizer alta coesão e design baixo acoplamento, a classe pode ter uma boa legibilidade, escalabilidade e facilidade de manutenção. Temos que pensar sobre o design da interface do tempo, gastar tempo, considerar o modelo de negócio, incluindo, se possível mudanças no futuro para fazer alguns pré-julgamento. Assim, para o abstrato, para entender o modelo de negócios é muito importante.

Aqui olhamos para um pedaço de código, um comportamento animal a descrição abstrata.

//描述动物行为的接口
public interface IAnimal {
    void eat();
    void fly();
    void swim();
}
//鸟类
public class Bird implements IAnimal {
    public void eat() {
    }

    public void fly() {
    }

    public void swim() {
    }
}
//狗
public class Dog implements IAnimal {
    public void eat() {
    }

    public void fly() {
    }

    public void swim() {
    }
}

Como pode ser visto, o método Swim Brid () só pode estar vazio, eo método cão Fly () é obviamente impossível. Neste momento, estamos focados em comportamento animal diferente para projetar diferentes interfaces foram projetadas interfaces de IEatAnimal, IFlyAnimal e ISwimAnimal, olhada no código:

public interface IEatAnimal {
    void eat();
}
public interface IFlyAnimal {
    void fly();
}
public interface ISwimAnimal {
    void swim();
}

Neste ponto só precisa implementar Dog IEatAnimal e interface de ISwimAnimal pode ser, por isso, a clareza.

public class Dog implements IEatAnimal,ISwimAnimal {

    public void eat() {
    }

    public void swim() {
    }
}

princípio Dmitry

Dimitris princípio (Lei de Deméter LOD) refere-se a um objecto a ser mantido a uma compreensão mínimo de outros objectos, também conhecido como o princípio menos conhecido (Least Princípio Conhecimento, LKP), para minimizar o grau de acoplamento entre a classe e classe. Dimitris princípio ênfase principal: comunicar apenas com amigos, não falar com estranhos. Aparece nos parâmetros variáveis ​​membro, de entrada e de saída do processo podem ser referidos como membros da classe amigo de classe, agora dentro para fora corpo do método não pertence à categoria amigos de classe.

Agora projetar um sistema de permissões, chefe precisa descobrir o número de cursos para liberar a linha. Neste momento, chefe Teamleader para encontrar estatísticas, Teamleader resultados estatísticos e depois dizer Boss, vamos olhar para o código:

//课程类
public class Course {
}
//TeamLeader类
public class TeamLeader {
    public void checkNumberOfCourses(List<Course> courses){
        System.out.println("目前已经发布的课程数量:"+courses.size());
    }
}
//Boss类
public class Boss {
    public void commandCheckNumber(TeamLeader teamLeader){
        //模拟BOSS一页一页往下翻页,TeamLeader实时统计
        List<Course> courseList = new ArrayList<Course>();
        for (int i = 0; i < 20; i++) {
            courseList.add(new Course());
        }
        teamLeader.checkNumberOfCourses(courseList);
    }
}
//调用方代码
public static void main(String[] args) {
        Boss boss = new Boss();
        TeamLeader teamLeader = new TeamLeader();
        boss.commandCheckNumber(teamLeader);
}

Eu escrevo para você, de fato, a função tem sido alcançado, o código parece ser nenhum problema, mas de acordo com os princípios da Demeter, chefe só quer resultados, não quer se comunicar diretamente com o Course. Teamleader estatísticas precisar fazer referência o objeto Course. Chefe e Claro que não são amigos e pode ser visto a partir do diagrama de classe a seguir:

O código a seguir para transformar:

//TeamLeader做与course的交流
public class TeamLeader {
    public void checkNumberOfCourses(){
        List<Course> courses = new ArrayList<Course>();
        for (int i = 0; i < 20; i++) {
            courses.add(new Course());
        }
        System.out.println("目前已经发布的课程数量:"+courses.size());
    }
}
//Boss直接与TeamLeader交流,不再直接与Course交流
public class Boss {
    public void commandCheckNumber(TeamLeader teamLeader){
        //模拟BOSS一页一页往下翻页,TeamLeader实时统计
        teamLeader.checkNumberOfCourses();
    }
}

Olhe para o diagrama de classe, chefe houve nenhum contato com o Curso

Tenha em mente aqui, aprendendo regra de design de software, não formam transtorno obsessivo-compulsivo, o encontro de cenários de negócios complexos, precisamos agir de acordo com as circunstâncias.

princípio da substituição Richter

princípio da substituição Richter (Liskov Substituição Priciple, LSP) meios que se, para cada tipo de objectos O1 T1, T2 são o tipo de objecto de O2 tal que todos programa definido P T1 são substituídas em todos os objectos O1 O2 , o comportamento do programa de P não foi alterada, então o tipo é um subtipo do tipo T2 T1.

Esta definição parece bastante abstrato, temos que re entender-lo. Pode ser entendida como uma entidade de software, se for aplicada a uma classe pai, então deve aplicar suas subclasses, a referência coloca a classe pai deve ser transparente para o uso do objeto que subclasse, objeto de subclasse pode ser substituído com o objeto pai, e a lógica do programa não é mudança, de acordo com esse entendimento, estendida ou seja: subclasse pode estender a funcionalidade da classe pai, mas não pode alterar a classe pai da função original.

(1) sub-classe pode aplicar a classe principal resumo, mas classe progenitor não sumário não pode ser coberta.

(2) sub-classe pode aumentar os seus próprios métodos.

As pré-condições (3) quando a subclasse da classe pai sobrecarregado, o método (isto é, o método de entrada, a referência) Método parâmetros de entrada do que a classe principal é mais relaxado.

(4) Quando o pai subclasse implementação da classe (reescrever ou recarregamento implementar os métodos abstract), pós condições do processo (isto é, a saída do método, o valor de retorno) ou mais rigorosa do que a mãe e o pai da mesma categoria.

princípio da substituição Use Richter tem as seguintes vantagens:

(1) constrangimentos herdado inundando, que é um reflexo do princípio de abertura e de fecho.

Robustez (2) para fortalecer o programa, quando a mudança colegas pode fazer uma boa compatibilidade, melhorar a capacidade de manutenção e escalabilidade do programa, reduzir o risco de introdução quando a demanda se torna.

Agora para descrever um cenário de negócios clássico, relações com princípio da substituição Richter quadrado, retangular e quadrangular explicação, todos nós sabemos que um quadrado é um retângulo especial, então você pode criar uma classe pai Retângulo:

//矩形类
public class Rectangle {
    private long hight;
    private long width;

    public long getHight() {
        return hight;
    }

    public void setHight(long hight) {
        this.hight = hight;
    }

    public long getWidth() {
        return width;
    }

    public void setWidth(long width) {
        this.width = width;
    }
}
//正方形类
public class Square extends Rectangle {
    private long length;

    public long getLength() {
        return length;
    }

    public void setLength(long length) {
        this.length = length;
    }

    @Override
    public long getHight() {
        return super.getHight();
    }

    @Override
    public void setHight(long hight) {
        super.setHight(hight);
    }

    @Override
    public long getWidth() {
        return super.getWidth();
    }

    @Override
    public void setWidth(long width) {
        super.setWidth(width);
    }
}
public class DemoTest {
    //在测试类中创建resize方法,长方形的宽应该大于等于高,我们让高一直增加,直至高等于宽,变成正方形。
    public static void resize(Rectangle rectangle) {
        while (rectangle.getWidth() >= rectangle.getHight()){
            rectangle.setHight(rectangle.getHight()+1);
            System.out.println("宽度:"+rectangle.getWidth()+"高度:"+rectangle.getHight());
        }
        System.out.println("resize方法结束!");
    }

    //测试代码如下
    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle();
        rectangle.setHight(10);
        rectangle.setWidth(20);
        resize(rectangle);
    }

Olhe para a saída do console, e finalmente encontrou a maior altura do que a largura, esta situação é normal no caso de um quadrado, agora vamos substituir a classe Retângulo em uma subclasse, não seria lógica, e contrário ao princípio da substituição de Richter, depois de substituir a classe pai em subclasses resultado do programa não atender às expectativas. Portanto, existem certos riscos do nosso projeto do código. princípio da substituição Richter só existe entre pais e classes filhas, as restrições de herança inundações. Vamos criar uma interface abstrata comum baseada em quadrados e retangulares quadrilátero interface Quadrangle:

public interface Quadrangle { 
    long getWidth(); 
    long getHeight(); 
}

Modificar classe retângulo retângulo:

public class Rectangle implements Quadrangle {
    private long height;
    private long width;

    public long getHeight() {
        return height;
    }

    public long getWidth() {
        return width;
    }

    public void setHeight(long height) {
        this.height = height;
    }

    public void setWidth(long width) {
        this.width = width;
    }
}

Modificar praça Categorias de classe quadrados:

public class Square implements Quadrangle {
    private long length;

    public long getLength() {
        return length;
    }

    public void setLength(long length) {
        this.length = length;
    }

    public long getWidth() {
        return 0;
    }

    public long getHeight() {
        return 0;
    }
}

Neste momento, se colocarmos um método parâmetro de redimensionamento () da classe em um quadrilátero Quadrangle, será dado método interno. Porque a Praça quadrado não tem setWidth () e setHeight () método tem. Por conseguinte, a fim de restringir a proliferação de herança, um redimensionamento () parâmetros método só pode rectângulo retangular. Claro, vamos continuar a explicar detalhadamente mais tarde nos cursos de modo design.

Síntese dos princípios multiplexagem

Síntese de multiplexagem princípios (Composto / agregado Reutilização Princípio, CARP) refere-se à composição objecto possível (tem-A) / (polimerizados contanis-a), em vez dos efeitos de herança de reutilização de software. Você pode tornar o sistema mais flexível, para reduzir o acoplamento entre a classe e classe, uma mudança relativamente pequena na influência da classe outras classes causado. Nossa herança é chamado de caixa branca reutilização, o que é equivalente a todos os detalhes de implementação são expostos para a subclasse. Composição / polimerização também conhecido como caixa preta objetos multiplexados não pode ser acessado fora os detalhes de implementação de classe. Para fazer projeto do código com base em cenários específicos de negócios, de fato, necessidade de seguir o modelo OOP. Ou em operações de banco de dados, por exemplo, para criar as primeiras categorias DBConnection:

public class DBConnection { 
    public String getConnection(){ 
        return "MySQL 数据库连接"; 
    } 
}

Criando categorias ProdutoDao:

public class ProductDao{ 
    private DBConnection dbConnection; 
    public void setDbConnection(DBConnection dbConnection) { 
        this.dbConnection = dbConnection; 
    }
    public void addProduct(){ 
        String conn = dbConnection.getConnection(); 
        System.out.println("使用"+conn+"增加产品"); 
    } 
}

Esta é uma síntese muito típico multiplexação principais cenários. No entanto, os projetos atuais, DbConnection não é uma abstração, não a expansão do sistema fácil. O sistema atual suporta a conexão de banco de dados MySQL, assumindo que as mudanças de negócios, operações de banco de dados para apoiar a camada de banco de dados Oracle. Claro, podemos adicionar suporte para o método de banco de dados Oracle em DbConnection no. Mas contrário ao princípio de abertura e fechamento. Na verdade, não temos de modificar o Dao código, DbConnection irá modificar o abstrato, olhada no código:

public abstract class DBConnection { 
    public abstract String getConnection(); 
}

Então, a lógica puxado MySQL:

public class MySQLConnection extends DBConnection { 
    @Override 
    public String getConnection() { 
        return "MySQL 数据库连接"; 
    } 
}

A Oracle re-criar o suporte lógico de:

public class OracleConnection extends DBConnection { 
    @Override 
    public String getConnection() { 
        return "Oracle 数据库连接"; 
    } 
}

A escolha particular para a camada de aplicação, procure diagrama de classes:

Resumo dos Princípios de Design

Aprender os princípios de design, aprender os padrões de projeto básico. No processo de desenvolvimento real, não requerem necessariamente que todo o código segue o princípio de design, temos de considerar mão de obra, tempo, custo, qualidade, e não deliberadamente busca da perfeição, a seguir os princípios de design em cena apropriado, encarna uma espécie de trade-offs, nos ajudar a projetar uma estrutura de código mais elegante.

Acho que você gosta

Origin www.cnblogs.com/whgk/p/12465380.html
Recomendado
Clasificación