一、实验目的
- 理解面向对象设计原则和常用设计模式;
- 理解并掌握工厂模式的概念和实现;
- 理解并掌握抽象工厂模式的概念和实现;
- 理解用反射技术+配置文件对工厂模式进行改进的方法
二、工厂模式实验
利用“反射技术+读取配置文件”的方法对简易计算器程序做改进
1、工厂模式与简单工厂模式的区别
简单工厂模式:一个工厂创建多个产品
工厂模式:每个产品都有对应的工厂进行生产,使用Factory模式替代new创建对象
抽象工厂模式:使用迭代模式创建对象
2、Properties类(介绍)
java中提供了配置文件的操作类Properties,Properties常用方法:
//设置properties键值对
properties.setProperty(String key, String value);
//获取properties值
properties.getProperty(String key);
//从输入流中读取属性列表(键值对)
properties.load(InputStream inStream);
properties,load(new FileInputStream("路径")
//按简单的面向行的格式从输入字符流中读取属性列表(键值对)
properties.load(Reader reader);
//将XML文档所表示的所有属性加载到properties中
properties.loadFromXML(InputStream in);
//以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键值对)写入输出流
properties.store(OutputStream out, String comments);
//以适合使用 load(Reader) 方法的格式,将此 Properties 表中的属性列表(键值对)写入输出字符
properties.store(Writer writer, String comments);
3、总结:通过读取配置文件的形式可以实现代码的深层次解耦,在java编程中,配置文件的重要性更是不言而喻。java编程有一条不成文的规定就是:“约定大于配置,配置大于代码”意思就是能用约定的就不去配置,能用配置文件搞定的就不去写代码。
4、代码
IFactory.java
package pac01;
interface IFactory {
Operation createOperation(String A,String B);
}
FactoryAdd.java
package pac01;
class FactoryAdd implements IFactory {
@Override
public Operation createOperation(String A,String B) {
return new OperationAdd();
}
}
FactoryDiv.java
package pac01;
class FactoryDiv implements IFactory{
@Override
public Operation createOperation(String A,String B) {
return new OperationDiv();
}
}
FactoryMul.java
package pac01;
class FactoryMul implements IFactory {
@Override
public Operation createOperation(String A,String B) {
return new OperationMul();
}
}
FactorySub.java
package pac01;
class FactorySub implements IFactory {
@Override
public Operation createOperation(String A,String B) {
return new OperationSub();
}
}
Properties.java
package io;
import java.io.InputStream;
public class Properties {
public static void main (String[] args){
// 获取class的包装类class
Class propertiesClass = Properties.class;
// 类加载器类:负责加载类的对象
ClassLoader classLoader = propertiesClass.getClassLoader();
// get得到资源作为文件流 (获取文件流)
InputStream inputStream = classLoader.getResourceAsStream("jdb.properties");
// System.out.println(inputStream);
}
}
jdbc.properties
+=pac01.FactoryAdd
-=pac01.FactorySub
*=pac01.FactoryMul
/=pac01.FactoryDiv
Test.java
package pac01;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Scanner;
public class Test{
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
try {
Scanner input = new Scanner(System.in);
System.out.print("请输入数字A: ");
String strNumberA = input.nextLine();
System.out.print("请输入+-*/: ");
String strType = input.nextLine();
System.out.print("请输入数字B: ");
String strNumberB = input.nextLine();
Properties properties = new Properties();
InputStream is = new FileInputStream(new File("src/jdbc.properties"));
properties.load(is);
is.close();
String className = properties.getProperty(strType);
IFactory factory = (IFactory) Class.forName(className).newInstance();
Operation oper = factory.createOperation(strNumberA,strNumberB);
System.out.println("结果为" + oper.getResult(strNumberA, strNumberB));
} catch (Exception e) {
System.out.println("除数不能为零");
}
}
}
其余代码与上期相同,详见软件工程综合实践】工厂模式之简易四则运算器(完整代码)
三、蛋糕店升级版
1、Diagrams
2、代码
BananaCakeFactory.java
public class BananaCakeFactory implements IFactory{
@Override
public Cake createCake(String type){
return new BananaCake();
}
}
CheeseCakeFactory.java
class CheeseCakeFactory implements IFactory{
@Override
public Cake createCake(String type){
return new CheeseCake();
}
}
ChocolateCakeFactory.java
class ChocolateCakeFactory implements IFactory{
@Override
public Cake createCake(String type){
return new ChocolateCake();
}
}
LemonCakeFactory、StrawberryCakeFactory类似
IFactory.java
interface IFactory {
Cake createCake(String type);
}
cake.properties
Strawberry=pac01.StrawberryCake
Lemon=pac01.LemonCake
Banana=pac01.BananaCake
Chocolate=pac01.ChocolateCake
Cheese=pac01.CheeseCake
BananaCake.java
package pac01;
public class BananaCake extends Cake {
@Override
public void addMilk() {
System.out.println("给蛋糕加牛奶!");
}
@Override
public void addFlour() {
System.out.println("给蛋糕加面粉!");
}
@Override
public String getName() {
return "香蕉蛋糕";
}
}
CheeseCake.java
package pac01;
public class CheeseCake extends Cake{
@Override
public void addMilk() {
System.out.println("给蛋糕加牛奶!");
}
@Override
public void addFlour() {
System.out.println("给蛋糕加面粉!");
}
@Override
public String getName() {
return "芝士蛋糕";
}
}
ChocolateCake.java
package pac01;
public class ChocolateCake extends Cake{
@Override
public void addMilk() {
System.out.println("给蛋糕加牛奶!");
}
@Override
public void addFlour() {
System.out.println("给蛋糕加面粉!");
}
@Override
public String getName() {
return "巧克力蛋糕";
}
}
Client.java
package pac01;
import sun.security.krb5.internal.crypto.CksumType;
import java.io.*;
import java.util.Properties;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
Scanner input =new Scanner(System.in);
CakeStore cakeStore = new CakeStore();
cakeStore.welcome();
String type = input.nextLine();
Properties properties = new Properties();
InputStream is = new FileInputStream(new File("src/cake.properties"));
properties.load(is);
is.close();
String className = properties.getProperty(type);
IFactory factory = (IFactory) Class.forName(className).newInstance();
Cake cake = factory.createCake(type);
cake.addMilk();
cake.addFlour();
System.out.println(cake.getName(type)+"新鲜出炉~");
cakeStore.goodbye();
}
}