用Java实现简单计算器未使用模式
首先我们定义加减乘除四个不同的方法然后在Main函数中通过用户输入不同的运算符调用各自的函数来得出结果
public class Add
{
private int num1;
private int num2;
public Add(int num1,int num2){
this.num1 = num1;
this.num2 = num2;
}
public int GetResult(){
return num1 + num2;
}
}
public class Sub
{
private int num1;
private int num2;
public Sub(int num1,int num2){
this.num1 = num1;
this.num2 = num2;
}
public int GetResult(){
return num1 - num2;
}
}
public class Mul
{
private int num1;
private int num2;
public Mul(int num1,int num2){
this.num1 = num1;
this.num2 = num2;
}
public int GetResult(){
return num1 * num2;
}
}
public class Div
{
private int num1;
private int num2;
public Div(int num1,int num2){
this.num1 = num1;
this.num2 = num2;
}
public int GetResult(){
return num1 / num2;
}
}
public static void main(String[] args)
{
int numberA,numberB;
char oper = '+';
double result=0;
Scanner sc = new Scanner(System.in);
System.out.println("numberA=");
numberA = sc.nextInt();
System.out.println("numberB=");
numberB = sc.nextInt();
System.out.print("输入运算符(+-*/):");
oper = (sc.next()).charAt(0);
Add a = new Add(numberA,numberB);
Sub s = new Sub(numberA,numberB);
Mul m = new Mul(numberA,numberB);
Div d = new Div(numberA,numberB);
switch (oper)
{
case '+': result = a.GetResult();break;
case '-': result = s.GetResult();break;
case '*': result = m.GetResult();break;
case '/': result = d.GetResult();break;
}
System.out.println("numberA" + oper + "numberB" + " = " + Double.toString(result));
}
使用简单工厂
为了优化和重构这个计算器程序,我们引入了简单工厂模式。在这个模式中,我们通过一个工厂类来生产不同的计算器对象。具体实现如下:
我们定义了一个接口operator,接口里有个抽象方法GetResult方法里面传了两个参数,所有实现该接口的都必须实现这个方法。
public interface Operator
{
public abstract int GetResult(int num1,int num2);
}
public class OperatorFactory{
public static Object GetOperator(char oper){
Object o = null;
try {
switch(oper){
case '+':o = new Add();break;
case '-':o = new Sub();break;
case '*':o = new Mul();break;
case '/':o = new Div();break;
default:
throw new UnexpectedException("目前不支持该运算\n");
}
}catch (Exception e){
e.printStackTrace();
return null;
}
return o;
}
}
在该代码中,OperatorFactory类充当了工厂类的角色,GetOperator方法是工厂方法,用于根据传入的操作符返回相应的操作符对象
客户端则通过调用GetOperator方法来获取相应的操作符对象,然后调用操作符对象的GetResult方法进行计算。
值得注意的是,该代码使用了异常处理来处理运算符未知的情况,同时也使用了反射机制来实现工厂方法。通过使用反射机制,我们可以避免在工厂类中对具体类进行硬编码,从而使得代码更加灵活和易于扩展。
add方法
public class Add implements Operator{
public Add() {}
public int GetResult(int num1,int num2){
return num1 + num2;
}
}
public class Div implements Operator{
public Div() {}
public int GetResult(int num1,int num2){
return num1 / num2;
}
}
public class Mul implements Operator{
public Mul() {}
public int GetResult(int num1,int num2){
return num1 * num2;
}
}
public class Sub implements Operator{
public Sub() {}
public int GetResult(int num1,int num2){
return num1 - num2;
}
}
Main方法
public static void main(String[] args){
int numberA,numberB;
char oper = '+';
double result=0;
Scanner sc = new Scanner(System.in);
System.out.println("numberA=");
numberA = sc.nextInt();
System.out.println("numberB=");
numberB = sc.nextInt();
System.out.print("输入运算符(+-*/):");
oper = (sc.next()).charAt(0);
Operator o = null;
o = (Operator)OperatorFactory.GetOperator(oper);
if (o != null)
result = o.GetResult(numberA,numberB);
System.out.println("numberA" + oper + "numberB" + " = " + Double.toString(result));
}
首先,代码调用了OperatorFactory类的静态方法GetOperator,该方法接收一个字符参数oper,用于指定要创建的运算符类型。然后,代码使用switch语句根据传入的参数oper,选择创建对应的运算符对象。如果传入的参数不是支持的运算符,则抛出异常。
然后,代码将创建的运算符对象赋值给变量o。由于GetOperator方法返回的是Object类型,而o是Operator类型,因此需要将返回值进行类型转换。这里使用了强制类型转换将Object类型转换为Operator类型。
这样,变量o就包含了一个根据传入参数oper创建的运算符对象。之后,可以调用o的GetResult方法来执行相应的运算。
使用简单工厂-反射机制
为了进一步优化和扩展我们的计算器程序,我们使用反射机制来实现工厂模式的灵活性和扩展性。
public interface Operator
{
public abstract int GetResult(int num1,int num2);
}
package operator;
import java.lang.reflect.InvocationTargetException;
public class OperatorFactory{
public static Object GetOperator(char oper){
Object o = null;
Class<?> clazz;
try {
clazz = Class.forName(XMLUtil.getString(oper));
//o = clazz.newInstance();
try {
o = clazz.getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return o;
}
}
package operator;
import java.io.File;
import java.rmi.UnexpectedException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XMLUtil {
public static String getString(char oper) {
String cName = null;
try{
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc = builder.parse(new File("src/config.xml"));
NodeList nl = doc.getElementsByTagName("className");
Node classNode = null;
switch(oper){
case '+':classNode = nl.item(0).getFirstChild();break;
case '-':classNode = nl.item(1).getFirstChild();break;
case '*':classNode = nl.item(2).getFirstChild();break;
case '/':classNode = nl.item(3).getFirstChild();break;
default:
throw new UnexpectedException("目前不支持该运算\n");
}
cName = classNode.getNodeValue();
}catch (Exception e){
e.printStackTrace();
return null;
}
return cName;
}
}
Config.xml
<config>
<className>operator.Add</className>
<className>operator.Sub</className>
<className>operator.Mul</className>
<className>operator.Div</className>
</config>
package operator;
public class Add implements Operator{
public Add() {}
public int GetResult(int num1,int num2){
return num1 + num2;
}
}
package operator;
public class Div implements Operator{
public Div() {}
public int GetResult(int num1,int num2){
return num1 / num2;
}
}
package operator;
public class Mul implements Operator{
public Mul() {}
public int GetResult(int num1,int num2){
return num1 * num2;
}
}
package operator;
public class Sub implements Operator{
public Sub() {}
public int GetResult(int num1,int num2){
return num1 - num2;
}
}
package operator;
import java.util.Scanner;
public class Application
{
public static void main(String[] args){
int numberA,numberB;
char oper = '+';
double result=0;
Scanner sc = new Scanner(System.in);
System.out.println("numberA=");
numberA = sc.nextInt();
System.out.println("numberB=");
numberB = sc.nextInt();
System.out.print("输入运算符(+-*/):");
oper = (sc.next()).charAt(0);
Operator o = null;
o = (Operator)OperatorFactory.GetOperator(oper);
if (o != null)
result = o.GetResult(numberA,numberB);
System.out.println("numberA" + oper + "numberB" + " = " + Double.toString(result));
}
}
使用工厂方法模式
public class Add implements Operator{
public int GetResult(int num1,int num2){
return num1 + num2;
}
}
class AddOperatorFactory implements OperatorFactory{
public Object GetOperator() {
return new Add();
}
}
public class Div implements Operator{
public int GetResult(int num1,int num2){
return num1 / num2;
}
}
public class DivOperatorFactory implements OperatorFactory{
public Object GetOperator(){
return new Div();
}
}
public class Factory {
public static Object GetOperator(OperatorFactory oFactory){
Object o = null;
o = oFactory.GetOperator();
return o;
}
}
public class Mul implements Operator{
public int GetResult(int num1,int num2){
return num1 * num2;
}
}
public class MulOperatorFactory implements OperatorFactory{
public Object GetOperator(){
return new Mul();
}
}
public interface Operator{
public abstract int GetResult(int num1,int num2);
}
public interface OperatorFactory{
public abstract Object GetOperator();
}
public class Sub implements Operator{
public int GetResult(int num1,int num2){
return num1 - num2;
}
}
public class SubOperatorFactory implements OperatorFactory{
public Object GetOperator(){
return new Sub();
}
}
public static void main(String[] args) {
int numberA,numberB;
char oper = '+';
double result=0;
Scanner sc = new Scanner(System.in);
System.out.println("numberA=");
numberA = sc.nextInt();
System.out.println("numberB=");
numberB = sc.nextInt();
System.out.print("输入运算符(+-*/):");
oper = (sc.next()).charAt(0);
OperatorFactory oFactory = null;
Operator o = null;
switch (oper){
case '+': oFactory = new AddOperatorFactory();break;
case '-': oFactory = new SubOperatorFactory();break;
case '*': oFactory = new MulOperatorFactory();break;
case '/': oFactory = new DivOperatorFactory();break;
}
o = (Operator)Factory.GetOperator(oFactory);
if (o != null)
result = o.GetResult(numberA,numberB);
System.out.println("numberA" + oper + "numberB" + " = " + Double.toString(result));
}
使用不同的设计模式可以让我们更好地组织代码、提高代码的复用性和可维护性,同时还可以让我们更好地解决一些特定的编程问题。
在实践中,我发现选择适合场景的设计模式往往能够让代码更加简洁明了,同时也能够提高代码的可读性和可维护性。例如,在计算器程序中,使用简单工厂模式和工厂方法模式可以让我们更好地组织和管理计算器对象,同时也方便了后续的扩展和维护。
此外,使用不同的设计模式还可以让我们更好地理解和运用面向对象编程的思想,例如将类的职责分离,遵循单一职责原则,减少代码的耦合度等。因此,学习和掌握不同的设计模式对于提高编程技能和水平有着非常重要的意义。