【设计模式项目】【GUI计算器】

文章目录

  • 实例1
    • 前言
    • 设计模式的使用
      • 工厂模式:
      • 策略模式:
      • 监听器模式:
      • 异常处理:
      • 设计模式的作用
    • 完整代码实现
  • 实例2
    • 前言
    • 设计模式
      • 工厂模式(Factory Pattern):
      • 策略模式(Strategy Pattern):
      • 监听器模式(Listener Pattern):
    • 完整代码

实例1

前言

由于Java 课程设计已经完成前期的计算器GUI设计,以及功能实现,现在基于之前的基础,进行设计模式的应用,以完善软件设计。

如果还不了解之前GUI设计的童鞋,可以先查看【Java课程设计】【图形界面程序】【计算器】。

设计模式的使用

使用了以下设计模式:

工厂模式:

工厂模式被用于创建不同类型的操作对象。Operation 接口充当了工厂模式中的产品,每个具体的操作类(例如 Addition、Subtraction 等)都实现了该接口。在 Calculation 类中,根据操作符的类型,使用工厂模式创建了相应的操作对象。

策略模式:

策略模式用于将不同的操作封装成独立的策略,并使它们可以相互替换。Operation 接口代表了策略的抽象,每个具体的操作类都实现了该接口并提供了自己的实现。在 Calculation 类中,根据用户选择的操作符,选择相应的操作策略,并将计算委托给所选策略。

监听器模式:

通过实现 ActionListener 接口,可以为按钮添加监听器,以响应按钮的点击事件。在 Calculation 类中,通过为按钮添加监听器,实现了按钮的点击事件处理。

异常处理:

在 Division 类的 performOperation 方法中,通过抛出 ArithmeticException 异常来处理除以零的情况。在 Calculation 类中,在执行除法操作时,捕获 ArithmeticException 异常,并将错误消息显示在文本框中。

设计模式的作用

这些设计模式的使用让代码更具可扩展性、灵活性和可维护性。工厂模式和策略模式使得添加新的操作变得简单,可以轻松地扩展计算器的功能。监听器模式用于处理用户界面的交互,使得按钮点击事件得以处理。异常处理机制增强了代码的健壮性,能够适当地处理除以零的异常情况。

完整代码实现

package cal1;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

interface Operation {
    double performOperation(double number1, double number2) throws ArithmeticException;
}

class Addition implements Operation {
    @Override
    public double performOperation(double number1, double number2) {
        return number1 + number2;
    }
}

class Subtraction implements Operation {
    @Override
    public double performOperation(double number1, double number2) {
        return number1 - number2;
    }
}

class Multiplication implements Operation {
    @Override
    public double performOperation(double number1, double number2) {
        return number1 * number2;
    }
}

class Division implements Operation {
    @Override
    public double performOperation(double number1, double number2) throws ArithmeticException {
        if (number2 != 0)
            return number1 / number2;
        else
            throw new ArithmeticException("ERROR: Division by zero");
    }
}

class Modulus implements Operation {
    @Override
    public double performOperation(double number1, double number2) {
        return number1 % number2;
    }
}

class SquareRoot implements Operation {
    @Override
    public double performOperation(double number1, double number2) {
        return Math.sqrt(number1);
    }
}

class Square implements Operation {
    @Override
    public double performOperation(double number1, double number2) {
        return number2 * number2;
    }
}

class Calculation {
    double number1, number2; //记录运算的两个数字
    Operation operation;
    boolean unfinishedReading;
    Frame frame = new Frame("高齐勉的计算器!");
    TextField inputBox = new TextField(30);
    Button[] button = new Button[20];

    Calculation() {
        //设置输入文本框位置
        frame.setBounds(200, 200, 400, 320);
        frame.add(inputBox, BorderLayout.NORTH);
        //设置按钮布局
        Panel panel = new Panel();
        panel.setLayout(new GridLayout(5, 4, 3, 3));
        //设置按钮,并将按钮加入panel
        String[] s = {"sqrt", "<-", "AC", "%", "7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", "0", ".", "=", "/"};
        for (int i = 0; i < s.length; i++) {
            button[i] = new Button(s[i]);
            button[i].addActionListener(new ActionListen());
            panel.add(button[i]);
        }
        frame.add(panel, BorderLayout.CENTER);//将panel设置在中部区域
        frame.setVisible(true);//设置窗口可见
        frame.addWindowListener(new WindowAdapter() {//窗口监听器,注册监听,可以关闭窗口
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    public class ActionListen implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {//获取事件源的标签
            String label = e.getActionCommand();
            if (label.equals("=")) {
                number2 = Double.parseDouble(inputBox.getText());
                unfinishedReading = true;

                try {
                    double result = operation.performOperation(number1, number2);
                    inputBox.setText(String.valueOf(result));
                } catch (ArithmeticException ex) {
                    inputBox.setText("ERROR");
                }
            } else if (label.equals("+") || label.equals("*") || label.equals("/") || label.equals("%") || label.equals("sqrt")) {
                number1 = Double.parseDouble(inputBox.getText());

                switch (label) {
                    case "+":
                        operation = new Addition();
                        break;
                    case "-":
                        operation = new Subtraction();
                        break;
                    case "*":
                        operation = new Multiplication();
                        break;
                    case "/":
                        operation = new Division();
                        break;
                    case "%":
                        operation = new Modulus();
                        break;
                    case "sqrt":
                        operation = new SquareRoot();
                        break;
                }

                unfinishedReading = false;
            } else if (label.equals("-")) {
                if (!unfinishedReading) {
                    inputBox.setText("-");
                    unfinishedReading = true;
                } else {
                    number1 = Double.parseDouble(inputBox.getText());
                    operation = new Subtraction();
                    unfinishedReading = false;
                }
            } else if (label.equals("<-")) {
                String expression = inputBox.getText();
                if (expression.length() != 0) {
                    expression = expression.substring(0, expression.length() - 1);
                    inputBox.setText(expression);
                } else if (expression.length() == 0 && inputBox.getText().length() != 0)
                    // 对于计算结果后避免删除键不能清楚结果显示
                    inputBox.setText(expression);
            } else if (label.equals("AC")) {
                inputBox.setText("");
                unfinishedReading = false;
            } else {
                String s = inputBox.getText();
                if (!unfinishedReading)
                    inputBox.setText(label);
                else
                    inputBox.setText(s + label);
                unfinishedReading = true;
            }
        }
    }

    public static void main(String[] args) {
        new Calculation();
    }
}

实例2

前言

【特别感谢】
下面的代码来自我的好基友(智子、),和前文一样,都是改进的产品,如果不懂内部逻辑,移步至简单计算器 Java图形化界面编程。

设计模式

工厂模式(Factory Pattern):

工厂模式用于封装对象的创建过程,使得代码更具灵活性和可维护性。在这个例子中,我们使用了工厂模式来创建不同的数学运算对象(Operation)。OperationFactory类充当工厂,根据给定的运算符创建相应的运算对象。通过将对象的创建委托给工厂,我们可以方便地添加新的运算类型,而无需修改主要的业务逻辑。

策略模式(Strategy Pattern):

策略模式允许我们在运行时选择算法或行为,将其封装在独立的对象中。在这个例子中,每个数学运算(如加法、减法、乘法等)都被封装在实现了Operation接口的具体类中。通过使用策略模式,我们可以动态地切换不同的运算算法,而无需修改主要的计算器逻辑。在按钮的事件监听器中,根据用户选择的运算符,我们使用相应的运算策略对象执行计算操作。

监听器模式(Listener Pattern):

在这个例子中,使用了监听器模式来处理按钮的点击事件。主要使用了以下几个监听器类:

NumListener(数字按钮监听器类):实现了ActionListener接口,用于处理数字按钮的点击事件。当用户点击数字按钮时,相应的数字会显示在文本框中。

OperatListener(操作符按钮监听器类):同样实现了ActionListener接口,用于处理操作符按钮的点击事件。当用户点击操作符按钮时,将当前的操作数(如果有的话)和操作符保存起来,以备后续计算使用。

EqualListener(等号按钮监听器类):同样实现了ActionListener接口,用于处理等号按钮的点击事件。当用户点击等号按钮时,根据之前保存的操作数和操作符,执行相应的数学运算,并将结果显示在文本框中。

这些监听器通过addActionListener方法将自身注册到对应的按钮上,以便在按钮被点击时接收到事件通知并执行相应的逻辑。

监听器模式允许我们将事件处理逻辑与事件源对象(例如按钮)分离,从而实现松耦合的设计。通过注册不同的监听器,我们可以为不同的按钮定义不同的行为,并且可以轻松地扩展和修改事件处理逻辑。

完整代码

package calZhizi;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import static java.awt.Color.blue;

public class Calculation {
    // 操作数
    double x, y;
    Operation operation;
    boolean flag;
    Frame frame = new Frame("智子的计算器!");
    TextField tf = new TextField(30);
    Button[] b = new Button[20];

    public void init() {
        // 北部区域放置文本框
        frame.add(tf, BorderLayout.NORTH);
        Panel panel = new Panel();
        panel.setLayout(new GridLayout(4, 5, 2, 2));
        // 设置按钮
        String s = "+-*/%";
        for (int i = 0; i < 10; i++) {// 运算数
            b[i] = new Button(i + "");
            b[i].setForeground(blue);
        }
        for (int i = 0; i < 5; i++) {// 运算符
            b[i + 10] = new Button(s.charAt(i) + "");
            b[i + 10].setForeground(blue);
        }
        String[] t = {"sqrt", "^2", "^3", "=", "."};
        for (int i = 0; i < 5; i++) {
            b[i + 15] = new Button(t[i]);
            b[i + 15].setForeground(blue);
        }

        // 按钮注册监听
        for (int i = 0; i < 10; i++) {// 操作数注册监听
            b[i].addActionListener(new NumListener());
        }

        for (int i = 10; i < 18; i++) {// 操作符注册监听
            if (i == 11) continue;
            b[i].addActionListener(new OperatListener());
        }
        b[11].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!flag) {
                    tf.setText("-");
                    flag = true;
                } else {
                    x = Double.parseDouble(tf.getText());
                    operation = OperationFactory.createOperation(e.getActionCommand());
                    flag = false;
                }
            }
        });
        // “=”注册监听
        b[18].addActionListener(new EqualListener());
        // “.”注册监听
        b[19].addActionListener(new NumListener());

        // 将按钮加入panel
        for (int i = 0; i < 20; i++) {
            panel.add(b[i]);
        }

        // 设置中部按钮
        frame.add(panel);

        // 窗口监听器 注册监听
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        // 设置窗口最优并可见
        frame.pack();
        frame.setVisible(true);
    }

    // 数字按钮监听器类
    public class NumListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            String t = e.getActionCommand();
            String s = tf.getText();
            if (flag == false)
                tf.setText(t);
            else
                tf.setText(s + t);
            flag = true;
        }
    }

    // 操作符按钮监听器类
    public class OperatListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            x = Double.parseDouble(tf.getText());
            operation = OperationFactory.createOperation(e.getActionCommand());
            flag = false;
        }
    }

    // 等号按钮监听器类
    public class EqualListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            y = Double.parseDouble(tf.getText());
            flag = true;

            if (operation != null) {
                double result = operation.calculate(x, y);
                tf.setText(String.valueOf(result));
            }
        }
    }

    public static void main(String[] args) {
        new Calculation().init();
    }
}

interface Operation {
    double calculate(double x, double y);
}

class Addition implements Operation {
    @Override
    public double calculate(double x, double y) {
        return x + y;
    }
}

class Subtraction implements Operation {
    @Override
    public double calculate(double x, double y) {
        return x - y;
    }
}

class Multiplication implements Operation {
    @Override
    public double calculate(double x, double y) {
        return x * y;
    }
}

class Division implements Operation {
    @Override
    public double calculate(double x, double y) {
        if (y != 0)
            return x / y;
        else
            return Double.POSITIVE_INFINITY;
    }
}

class Modulo implements Operation {
    @Override
    public double calculate(double x, double y) {
        return x % y;
    }
}

class SquareRoot implements Operation {
    @Override
    public double calculate(double x, double y) {
        return Math.sqrt(x);
    }
}

class Square implements Operation {
    @Override
    public double calculate(double x, double y) {
        return x * x;
    }
}

class Cube implements Operation {
    @Override
    public double calculate(double x, double y) {
        return x * x * x;
    }
}

class OperationFactory {
    public static Operation createOperation(String operator) {
        switch (operator) {
            case "+":
                return new Addition();
            case "-":
                return new Subtraction();
            case "*":
                return new Multiplication();
            case "/":
                return new Division();
            case "%":
                return new Modulo();
            case "sqrt":
                return new SquareRoot();
            case "^2":
                return new Square();
            case "^3":
                return new Cube();
            default:
                throw new IllegalArgumentException("Invalid operator: " + operator);
        }
    }
}

你可能感兴趣的:(JAVA的自学之路,设计模式,策略模式,java)