一、实验目的
- 掌握简单工厂模式和工厂方法模式的概念,能够灵活使用简单工厂模式和工厂方法模式解决相关问题。 二、实验内容 场景描述一: 在某OA系统中,系统根据对比用户在登录时输入的账号和密码以及在数据库中存储的账号和密码是否一致来进行身份验证,如果验证通过,则取出存储在数据库中的用户权限等级(以整数形式存储),根据不同的权限等级创建不同等级的用户对象,不同等级的用户对象拥有不同的操作权限。现使用简单工厂模式设计该系统。 三个等级对象:管理员、经理和员工。 变化权限:diff() 不变权限:same() 要求: 1、利用UML图给出相应的角色,并有相关描述; 2、给出程序代码,程序代码有恰当的注释; 3、文档格式正确,排版清晰。
1.对应的UML图如下图所示: 程序代码如下:
Client 类
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("输入输入身份账号");
String username=scanner.next();
System.out.println("输入密码");
String password=scanner.next();
int count = 0;
if(username.equals("Employee")&&password.equals("123")){
count=1;
}else if(username.equals("Manager")&&password.equals("123")){
count=2;
}else if(username.equals("Administrator")&&password.equals("123")){
count=3;
}else{
throw new Exception("输入错误!");
}
try {
UserFactory userFactory=new UserFactory();
User user = userFactory.getUser(count);
user.sameOperation();
user.diffOperation();
} catch (Exception e) {
e.printStackTrace();
}
}
}
UserFactory 类
public class UserFactory {
public User getUser(int permission) throws Exception {
if (permission==1) {
return new Employee();
}else if (permission==2) {
return new Manager();
}else if (permission==3) {
return new Administrator();
}else {
throw new Exception("输入错误");
}
}
}
User 类
public class User {
public void sameOperation(){
System.out.println("User sameOperation");
}
public void diffOperation(){
System.out.println("User diffOperation");
}
}
Employee 类
public class Employee extends User{
public void diffOperation(){
System.out.println("Employee sameOperation");
}
}
Manager 类
public class Manager extends User{
public void diffOperation(){
System.out.println("Manager diffOperation");
}
}
Administrator 类
public class Administrator extends User{
public void diffOperation(){
System.out.println("Administrator diffOperation");
}
}
试运行:
场景描述二: 某系统日志记录器要求支持多种日志记录方式,如文件记录、数据库记录等,且用户可以根据要求动态选择日志记录方式,现使用工厂方法模式设计该系统。 要求: 1、利用UML图给出相应的角色,并有相关描述; 2、给出程序代码,客户端不能使用具体工厂类的名称,要求使用配置文件+反射机制,程序代码有恰当的注释; 3、文档格式正确,排版清晰。 1.对应的UML图如下 图所示:
程序代码如下:
Client 类:
public class Client {
public static void main(String[] args) throws Exception {
Object bean = XMLUtil.getBean();
if(bean.getClass().getSimpleName().equals("FileLogFactory")){
FileLogFactory fileLogFactor=(FileLogFactory)bean;
Log log = fileLogFactor.createLog();
log.writeLog();
}else if(bean.getClass().getSimpleName().equals("DatabaseLogFactory")){
DatabaseLogFactory databaseLogFactory =(DatabaseLogFactory) bean;
Log log = databaseLogFactory.createLog();
log.writeLog();
}else {
throw new Exception("xml文件错误");
}
}
}
FactoryMethodconfig.xml
<?xml version="1.0"?>
<config>
<className>two.FileLogFactory</className>
</config>
XMLUtil类
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
public class XMLUtil
{
//该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
public static Object getBean()
{
try
{
//创建文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("homework-02/FactoryMethodconfig.xml"));
//获取包含类名的文本节点
NodeList nl = doc.getElementsByTagName("className");
Node classNode=nl.item(0).getFirstChild();
String cName=classNode.getNodeValue();
//通过类名生成实例对象并将其返回
Class c=Class.forName(cName);
Object obj=c.newInstance();
return obj;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
}
Log 接口:
public interface Log {
public void writeLog();
}
LogFactory 接口:
public interface LogFactory {
public Log createLog();
}
FileLogFactory 类:
public class FileLogFactory implements LogFactory{
@Override
public Log createLog() {
return new FileLog();
}
}
FileLog 类:
public class FileLog implements Log{
@Override
public void writeLog() {
System.out.println("FileLog!");
}
}
DatabaseLogFactory 类:
public class DatabaseLogFactory implements LogFactory{
@Override
public Log createLog() {
return new DataBaseLog();
}
}
DataBaseLog 类:
public class DataBaseLog implements Log{
@Override
public void writeLog() {
System.out.println("writeLog!");
}
}
场景描述三: 把实验1中的运算器用工厂方法模式实现。 要求: 1、画出UML类图; 2、给出程序代码,程序代码有恰当的注释; 3、文档格式正确,排版清晰。 1、UML类图如下:
2、程序代码如下:
Client类:
import java.util.Scanner;
public class Client{
public static void main(String[] args) {
System.out.println("输入第一个操作数");
Scanner scan = new Scanner(System.in);
double num1 = scan.nextDouble();
System.out.println("输入运算符");
String operation = scan.next();
System.out.println("输入第二个操作数");
double num2 = scan.nextDouble();
Operation oper=OperationFactory.getResult(operation);
oper.setNum1(num1);
oper.setNum2(num2);
double result=oper.getResult();
System.out.println(num1 + operation + num2 + "=" + result);
}
}
Operation 类:
public class Operation {
public double num1;
public 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 double getResult() {
double result=0;
return result;
}
}
OperationFactory 类:
interface OperationFactory { // 工厂接口
public static Operation getResult(String operator) {
Operation oper=null;
switch(operator) {
case"+":
oper=new AddOperation();
break;
case"-":
oper=new SubOperation();
break;
case"*":
oper=new ChengOperation();
break;
case"/":
oper=new ChuOperation();
break;
}
return oper;
}
}
//加法类
public class AddOperation extends Operation{
public double getResult() {
double result=0;
result=(num1+num2);
return result;
}
}
//减法类
public class SubOperation extends Operation{
public double getResult() {
double result=0;
result=(num1-num2);
return result;
}
}
//乘法类
public class ChengOperation extends Operation{
public double getResult() {
double result=0;
result=(num1*num2);
return result;
}
}
//除法类
public class ChuOperation extends Operation{
public double getResult() {
double result=0;
result=(num1/num2);
return result;
}
}
试运行: 三、思考 请问工厂方法模式相比简单工厂模式有哪些优点? 简单工厂模式:任何”东西“的子类都可以被生产,负担太重。当所要生产产品种类非常多时,工厂方法的代码量可能会很庞大。工厂方法模式就很好的减轻了工厂类的负担,把某一类/某一种东西交由一个工厂生产。 在遵循开闭原则(对拓展开放,对修改关闭)的条件下,简单工厂对于增加新的产品,无能为力。因为增加新产品只能通过修改工厂方法来实现。工厂方法模式在同时增加某一类 ”东西“ 并不需要修改工厂类,只需要添加生产这类 ”东西“ 的工厂即可,使得工厂类符合开放-封闭原则。
标签:return,软件设计,double,模式,public,result,new,工厂,class From: https://blog.51cto.com/histry/9098398