Pensando en el resumen del ejemplo de la calculadora pequeña

1. Diseño y pensamiento

1. Si no lo sabes, solo pregunta.

No sé cómo lidiarás con los problemas cuando los encuentres. Estoy acostumbrado a resolver las cosas por mi cuenta primero y luego buscar información para encontrar respuestas basadas en los resultados. A menudo pierdo la mayor parte de mi tiempo en esto. proceso y, a menudo, tomar un camino equivocado o tomar un camino repetitivo que otros ya han recorrido.

Es por eso que tenemos este subtítulo: solo pregunta si no lo sabes. Realmente hay muchos "gigantes" a nuestro alrededor. Pregúntale a los gigantes que te rodean con humildad y no te atrevas a preguntar por miedo o por miedo a que tus preguntas sean demasiado. nivel bajo. Esto es lo que significa "pararse sobre los hombros de gigantes": nuestros predecesores nos sentaron muchas bases y exploraron muchos caminos oscuros para que no tengamos que reinventar la rueda nuevamente. Cuando no comprende, no comprende o sus ideas están estancadas, es mejor pedir humildemente consejo a los "gigantes" que lo rodean.

2. Si la lógica no tiene sentido, haz un dibujo.

Cuando era joven, mi madre siempre me enseñó que "una buena memoria es peor que una mala escritura", lo que significaba que debía tomar más notas, poner más cosas en mi mente en papel y despejar mi mente a tiempo. Lo mismo sucedió hoy. Después de que la maestra me contó este pequeño ejemplo, seguí pensando en cómo implementarlo. Siempre miraba una cosa y perdía de vista la otra. Mi consideración no era lo suficientemente completa y el plan de implementación era contradictorio. .

Hasta que implementé las ideas en mi mente en la imagen, dibujé la primera versión del diagrama de flujo según mi propio pensamiento :
Insertar descripción de la imagen aquí
aunque se generó el diagrama de flujo, todavía había muchos lugares en él que no se podían implementar en el código. Entonces, después de discutir con el maestro, se me ocurrió una segunda versión del diagrama de flujo :
Insertar descripción de la imagen aquí
La segunda versión del diagrama de flujo aquí presta más atención al desacoplamiento y la implementación del código. Divide el cambio de operación y el resultado del cálculo en dos procesos para ordenar Las conexiones se hacen a través de objetos.

Efecto de realización:
Por favor agregue la descripción de la imagen.

2. Implementación del código

1. Implementación de código específico

Página de interfaz de usuario:

package com.zwb.awtui;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;

/**
 * @program: zwbStudy
 * @description:
 * @author: 翟文彪
 * @create: 2022-06-02 10:07
 **/
public class UI {
    
    
    public static Operation opera;
    public static JLabel labelOperation;

    public static void main(String[] args) {
    
    
        // 创建窗口
        JFrame jf = new JFrame("运算器");
        jf.setLayout(new FlowLayout());
        jf.setBounds(400,300,400,500);

        // 运算符按钮集合
        List<JButton> jButtonList = new ArrayList<>();

        // 按钮(通过读取配置文件默认加载)
        // 读取配置文件
        Properties properties = new Properties();
        String pat = "D:\\JAVA\\zwbStudy\\src\\main\\resources\\application.properties";
        File file = new File(pat);
        try {
    
    
            FileInputStream fileOutputStream = null;
            if (file.getParentFile().exists()) {
    
    
                fileOutputStream = new FileInputStream(file);
            }
            properties.load(fileOutputStream);
            String config = properties.getProperty("button");

            List<String> buttonList = new ArrayList<>();
            // 使用字符串分词器将";"作为分隔符分隔各个按钮
            StringTokenizer subString = new StringTokenizer(config,";");
            // 循环存储到buttonList中
            while (subString.hasMoreTokens()){
    
    
                buttonList.add(subString.nextToken());
            }
            for (String button : buttonList) {
    
    
                // 根据配置文件中的全路径实例化对象,创建页面上的按钮
                Class<?> newButton = null;
                newButton = Class.forName(button);
                ButtonObject jButton = (ButtonObject)newButton.newInstance();
                jButtonList.add(jButton.creatButton());
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }

        JButton equalsButton = new JButton("=");
        equalsButton.setEnabled(true);

        // 输入框
        JTextField textA = new JTextField(5);
        JTextField textB = new JTextField(5);

        // 标签
        labelOperation = new JLabel();
        JLabel labelResult = new JLabel();

        // 运算器执行区域
        jf.add(textA);
        jf.add(labelOperation);
        jf.add(textB);
        jf.add(equalsButton);
        jf.add(labelResult);

        // 运算符库
        for (JButton jButton : jButtonList) {
    
    
            jf.add(jButton);
            // 各个运算符加载上运算符监听事件
            OperationClickAction cli = new OperationClickAction();
            jButton.addMouseListener(cli);
        }

        // 给等于按钮加载上等于按钮监听事件
        equalsButton.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                opera.setNumberA(Double.valueOf(textA.getText()));
                opera.setNumberB(Double.valueOf(textB.getText()));
                labelResult.setText(String.valueOf(opera.getResult()));
            }
        });

        jf.setVisible(true);
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}

Clase y subclase abstractas del botón de operador:

package com.zwb.awtui;

import javax.swing.*;

/**
 * @program: zwbStudy
 * @description: 按钮
 * @author: 翟文彪
 * @create: 2022-06-10 15:09
 **/
public abstract class ButtonObject {
    
    
    protected abstract iFactory creatFactory();
    protected abstract JButton creatButton();
}

class ButtonAdd extends ButtonObject{
    
    
    @Override
    protected iFactory creatFactory() {
    
    
        return new Factory1();
    }
    @Override
    protected JButton creatButton() {
    
    
        JButton jButton = new JButton("+");
        jButton.setEnabled(true);
        return jButton;
    }
}

class ButtonSub extends ButtonObject{
    
    
    @Override
    protected iFactory creatFactory() {
    
    
        return new Factory2();
    }

    @Override
    protected JButton creatButton() {
    
    
        JButton jButton =  new JButton("-");
        jButton.setEnabled(true);
        return jButton;
    }
}

class ButtonMul extends ButtonObject{
    
    
    @Override
    protected iFactory creatFactory() {
    
    
        return new Factory3();
    }

    @Override
    protected JButton creatButton() {
    
    
        JButton jButton =  new JButton("*");
        jButton.setEnabled(true);
        return jButton;
    }
}
class ButtonDiv extends ButtonObject{
    
    
    @Override
    protected iFactory creatFactory() {
    
    
        return new Factory4();
    }

    @Override
    protected JButton creatButton() {
    
    
        JButton jButton =  new JButton("/");
        jButton.setEnabled(true);
        return jButton;
    }
}

Fábrica computacional:

package com.zwb.awtui;

/**
 * @program: zwbStudy
 * @description: 运算工厂
 * @author: 翟文彪
 * @create: 2022-06-05 10:52
 **/
public interface iFactory {
    
    
    Operation createOperation();
}

class Factory1 implements iFactory{
    
    
    @Override
    public Operation createOperation() {
    
    
        return new OperationAdd();
    }
}

class Factory2 implements iFactory{
    
    
    @Override
    public Operation createOperation() {
    
    
        return new OperationSub();
    }
}

class Factory3 implements iFactory{
    
    
    @Override
    public Operation createOperation() {
    
    
        return new OperationMul();
    }
}

class Factory4 implements iFactory{
    
    
    @Override
    public Operation createOperation() {
    
    
        return new OperationDiv();
    }
}

Clases y subclases abstractas de operadores.

package com.zwb.awtui;

/**
 * @program: zwbStudy
 * @description: 运算符抽象类与子类
 * @author: 翟文彪
 * @create: 2022-06-05 10:14
 **/
public abstract class Operation {
    
    
    private double numberA = 0;
    private double numberB = 0;

    public double getNumberA() {
    
    
        return numberA;
    }

    public void setNumberA(double numberA) {
    
    
        this.numberA = numberA;
    }

    public double getNumberB() {
    
    
        return numberB;
    }

    public void setNumberB(double numberB) {
    
    
        this.numberB = numberB;
    }

    public abstract double getResult();
}

class OperationAdd extends Operation {
    
    

    @Override
    public double getResult() {
    
    
        double result = 0;
        result = getNumberA() + getNumberB();
        return result;
    }
}

class OperationSub extends Operation {
    
    
    @Override
    public double getResult() {
    
    
        double result = 0;
        result = getNumberA() - getNumberB();
        return result;
    }
}

class OperationMul extends Operation {
    
    
    @Override
    public double getResult() {
    
    
        double result = 0;
        result = getNumberA() * getNumberB();
        return result;
    }
}

class OperationDiv extends Operation {
    
    
    @Override
    public double getResult() {
    
    
        double result = 0;
        try {
    
    
            if (getNumberB() == 0) {
    
    
                throw new Exception("除数不能为0");
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        result = getNumberA() / getNumberB();
        return result;
    }
}

Clase de escucha de eventos de botón

package com.zwb.awtui;

import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;

/**
 * @program: zwbStudy
 * @description: 按钮事件监听类
 * @author: 翟文彪
 * @create: 2022-06-10 14:40
 **/
public class OperationClickAction implements MouseListener {
    
    
    public static String operationText;

    @Override
    public void mouseClicked(MouseEvent mouseEvent) {
    
    
        //System.out.println("你点击的按钮名称为"+((JButton) (e.getSource())).getText());

        // 读取配置文件
        Properties properties = new Properties();
        String pat = "D:\\JAVA\\zwbStudy\\src\\main\\resources\\application.properties";
        File file = new File(pat);
        try {
    
    
            FileInputStream fileOutputStream = null;
            if (file.getParentFile().exists()) {
    
    
                fileOutputStream = new FileInputStream(file);
            }
            properties.load(fileOutputStream);
            String config = properties.getProperty(((JButton) (mouseEvent.getSource())).getText());
            // 根据配置文件中的全路径实例化对象,创建页面上的按钮
            Class<?> newButton = null;
            newButton = Class.forName(config);
            ButtonObject button = (ButtonObject) newButton.newInstance();
            // 创建对应的工厂对象
            iFactory factory = button.creatFactory();
            UI.opera = factory.createOperation();

            // 赋值给运算符文本
            UI.labelOperation.setText(((JButton) (mouseEvent.getSource())).getText());
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
    
    

    }

    @Override
    public void mouseReleased(MouseEvent e) {
    
    

    }

    @Override
    public void mouseEntered(MouseEvent e) {
    
    

    }

    @Override
    public void mouseExited(MouseEvent e) {
    
    

    }
}

2. Aunque tus reflejos sean buenos, no seas codicioso.

En el código que proporcioné anteriormente, el botón del operador inicial de la clase UI (clase cliente) se carga en el Marco leyendo la ruta completa de la clase en el archivo de configuración y reflexionando. Más tarde, durante la discusión con el profesor, también Se entiende que puede cargar botones sin usar la reflexión, porque todos sabemos cuántos botones deben cargarse, solo necesitamos crear instancias de todos los botones de subclase incluidos en la clase de botón.

El mayor problema aquí es el abuso de la reflexión. Aunque todos sabemos que la reflexión es muy conveniente y flexible, tiene una brecha en la eficiencia de ejecución en comparación con las operaciones de creación de instancias directas, porque la reflexión necesita leer el contenido del archivo de configuración y luego realizar la creación de instancias. operaciones.

Por lo tanto, aunque la reflexión es muy conveniente, aún es necesario prestar atención a la escena y al momento de uso.

3. Resumen y mejora

1. Mejora tecnológica

(1) Aprendí y entendí la programación GUI en Java desde la perspectiva del uso, y también amplíé el conocimiento en esta área
(2) El uso flexible de la reflexión, los métodos de fábrica y la relación entre clases pueden combinar varios objetos.

2. Mejora de los pensamientos

(1) Cuando encuentres dificultades, debes pedir consejo a tiempo y aprender a pararte sobre los hombros de gigantes.
(2) Debe tener conciencia de la situación general y ordenar el negocio y la estructura general mediante dibujos. No obtendrá la respuesta correcta si observa el problema de forma aislada y local. (3) Lo que piensa no es necesariamente lo que piensas, por
ejemplo En este pequeño ejemplo, no pude pensar en una solución adecuada para satisfacer las necesidades del maestro al principio, pero esto no significa que no exista tal solución. No limites tus pensamientos, mientras te atrevas a pensar y hacer, definitivamente obtendrás resultados.

Supongo que te gusta

Origin blog.csdn.net/zwb568/article/details/125227942
Recomendado
Clasificación