設計モデル——工場モデルの開発における応用(簡易計算機)
簡単な計算機を例に、ファクトリモードの使い方を説明します.
デザインモードを使用していない場合は、次のように書く可能性があります.
このように判断演算子に書くコードの繰返し率が高すぎる
次のように書くことができます.
(1)抽象的な計算クラス
(3)主関数は現在このように書くことができる
しかし,上記の方法はやはり問題があり,演算のたびに操作のクラス名を知り,newオブジェクトによってインスタンス化する.
簡単な工場モデルで実現します.
(1)OperationFactoryファクトリクラスを作成する(まず「+」演算を書く)
これにより演算を拡張できるが,工場メソッドの内容を変更し,外部は開放的であるが,内部は閉鎖的ではない.
私たちは今、工場方法モデルで実現しています.
(1)抽象工場の設立方法
(2)Add(加算)ファクトリメソッド抽象ファクトリメソッドインタフェースの実現
(3)MainClassではこう書いてあります
このように書くメリットは、演算を増やす(演算記号を増やす)場合、OperationやOperationFactoryを修正する必要がなく、対応する
XxxxOperationとXxxxOperationFactoryで良いのですが、このように書くとMainClassで演算子の判読も行われます.
反射技術を使用してカプセル化します.
(1)プロファイルoperationを書く.properties
+ = com.meritit.AddOperation
(2)構成情報を読み取るツールクラスを書く
(3)AddOperationFactoryにこう書く
(4)MainClass判断演算子は不要
これでファクトリメソッドモードを使用して簡単な計算機を完成しました.何か問題があれば指摘してください.
ソースのダウンロード:http://download.csdn.net/detail/lxq_xsyu/5907383
デザインモードを使用していない場合は、次のように書く可能性があります.
package com.meritit;
import java.util.Scanner;
public class MainClass {
public static void main(String[] args) {
double result = 0;
//1.
System.out.println("----- -----");
System.out.println(" ");
Scanner scan = new Scanner(System.in);
String strNum1 = scan.nextLine();
System.out.println(" ");
String oper = scan.nextLine();
System.out.println(" ");
String strNum2 = scan.nextLine();
//2.
if("+".equals(oper)){
result = Double.parseDouble(strNum1) + Double.parseDouble(strNum2);
}else if("-".equals(oper)){
result = Double.parseDouble(strNum1) - Double.parseDouble(strNum2);
}else if("*".equals(oper)){
result = Double.parseDouble(strNum1) * Double.parseDouble(strNum2);
}else if("/".equals(oper)){
result = Double.parseDouble(strNum1) / Double.parseDouble(strNum2);
}
//3.
System.out.println(strNum1 + oper + strNum2 + "=" + result);
}
}
このように判断演算子に書くコードの繰返し率が高すぎる
次のように書くことができます.
(1)抽象的な計算クラス
package com.meritit;
public abstract class Operation {
private double num1;
private double num2;
public double getNum1() {
return num1;
}
public void setNum1(double num1) {
this.num1 = num1;
}
public double getNum2() {
return num2;
}
public void setNum2(double num2) {
this.num2 = num2;
}
public abstract double getResult();
}
(2)具体的な加算実装クラスpackage com.meritit;
public class AddOperation extends Operation{
@Override
public double getResult() {
double result = this.getNum1() + this.getNum2();
return result;
}
}
(3)主関数は現在このように書くことができる
package com.meritit;
import java.util.Scanner;
public class MainClass {
public static void main(String[] args) {
double result = 0;
//1.
System.out.println("----- -----");
System.out.println(" ");
Scanner scan = new Scanner(System.in);
String strNum1 = scan.nextLine();
System.out.println(" ");
String oper = scan.nextLine();
System.out.println(" ");
String strNum2 = scan.nextLine();
double num1 = Double.parseDouble(strNum1);
double num2 = Double.parseDouble(strNum2);
//2.
if("+".equals(oper)){
Operation operation = new AddOperation();
operation.setNum1(num1);
operation.setNum2(num2);
result = operation.getResult();
}else if("-".equals(oper)){
result = Double.parseDouble(strNum1) - Double.parseDouble(strNum2);
}else if("*".equals(oper)){
result = Double.parseDouble(strNum1) * Double.parseDouble(strNum2);
}else if("/".equals(oper)){
result = Double.parseDouble(strNum1) / Double.parseDouble(strNum2);
}
//3.
System.out.println(strNum1 + oper + strNum2 + "=" + result);
}
}
しかし,上記の方法はやはり問題があり,演算のたびに操作のクラス名を知り,newオブジェクトによってインスタンス化する.
簡単な工場モデルで実現します.
(1)OperationFactoryファクトリクラスを作成する(まず「+」演算を書く)
package com.meritit;
public class OperationFactory {
public static Operation getOperation(String oper){
if("+".equals(oper)){
return new AddOperation();
}else{
return null;
}
}
}
(2)現在の主関数にはこのように書くことができます.package com.meritit;
import java.util.Scanner;
public class MainClass {
public static void main(String[] args) {
double result = 0;
//1.
System.out.println("----- -----");
System.out.println(" ");
Scanner scan = new Scanner(System.in);
String strNum1 = scan.nextLine();
System.out.println(" ");
String oper = scan.nextLine();
System.out.println(" ");
String strNum2 = scan.nextLine();
double num1 = Double.parseDouble(strNum1);
double num2 = Double.parseDouble(strNum2);
//2.
Operation operation = OperationFactory.getOperation(oper);
operation.setNum1(num1);
operation.setNum2(num2);
result = operation.getResult();
//3.
System.out.println(strNum1 + oper + strNum2 + "=" + result);
}
}
これにより演算を拡張できるが,工場メソッドの内容を変更し,外部は開放的であるが,内部は閉鎖的ではない.
私たちは今、工場方法モデルで実現しています.
(1)抽象工場の設立方法
package com.meritit;
public interface OperationFactory {
public Operation getOperation();
}
(2)Add(加算)ファクトリメソッド抽象ファクトリメソッドインタフェースの実現
package com.meritit;
public class AddOperationFactory implements OperationFactory{
@Override
public Operation getOperation() {
return new AddOperation();
}
}
(3)MainClassではこう書いてあります
package com.meritit;
import java.util.Scanner;
public class MainClass {
public static void main(String[] args) {
double result = 0;
//1.
System.out.println("----- -----");
System.out.println(" ");
Scanner scan = new Scanner(System.in);
String strNum1 = scan.nextLine();
System.out.println(" ");
String oper = scan.nextLine();
System.out.println(" ");
String strNum2 = scan.nextLine();
double num1 = Double.parseDouble(strNum1);
double num2 = Double.parseDouble(strNum2);
//2.
if("+".equals(oper)){
OperationFactory oFactory = new AddOperationFactory();
Operation operation = oFactory.getOperation();
operation.setNum1(num1);
operation.setNum2(num2);
result = operation.getResult();
}
//3.
System.out.println(strNum1 + oper + strNum2 + "=" + result);
}
}
このように書くメリットは、演算を増やす(演算記号を増やす)場合、OperationやOperationFactoryを修正する必要がなく、対応する
XxxxOperationとXxxxOperationFactoryで良いのですが、このように書くとMainClassで演算子の判読も行われます.
反射技術を使用してカプセル化します.
(1)プロファイルoperationを書く.properties
+ = com.meritit.AddOperation
(2)構成情報を読み取るツールクラスを書く
package com.meritit;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ConfigUtil {
public static String getConfig(String style){
Properties pro = new Properties();
InputStream inStream = ConfigUtil.class.getClassLoader().getResourceAsStream("operation.properties");
try {
pro.load(inStream);
} catch (IOException e) {
e.printStackTrace();
}
return pro.getProperty(style);
}
public static void main(String[] args) {
System.out.println(getConfig("+"));
}
}
(3)AddOperationFactoryにこう書く
package com.meritit;
public class AddOperationFactory implements OperationFactory{
@Override
public Operation getOperation(String oper)throws Exception{
String type = ConfigUtil.getConfig(oper);
return (Operation)Class.forName(type).newInstance();
}
}
(4)MainClass判断演算子は不要
package com.meritit;
import java.util.Scanner;
public class MainClass {
public static void main(String[] args) {
double result = 0;
//1.
System.out.println("----- -----");
System.out.println(" ");
Scanner scan = new Scanner(System.in);
String strNum1 = scan.nextLine();
System.out.println(" ");
String oper = scan.nextLine();
System.out.println(" ");
String strNum2 = scan.nextLine();
double num1 = Double.parseDouble(strNum1);
double num2 = Double.parseDouble(strNum2);
//2.
try {
OperationFactory oFactory = new AddOperationFactory();
Operation operation = oFactory.getOperation(oper);
operation.setNum1(num1);
operation.setNum2(num2);
result = operation.getResult();
} catch (Exception e) {
e.printStackTrace();
}
//3.
System.out.println(strNum1 + oper + strNum2 + "=" + result);
}
}
これでファクトリメソッドモードを使用して簡単な計算機を完成しました.何か問題があれば指摘してください.
ソースのダウンロード:http://download.csdn.net/detail/lxq_xsyu/5907383