目录
一、简单工厂模式
从字面意思看来就是要有一个工厂类,那么这个工厂类是干什么的呢? 创建并返回一个具体对象。
应用场景如下:
- 1.完全封装隔离具体实现,只通过客户端使用。
- 2.对外集中创建对象。
二、简单工厂模式角色
假如我们要做一个计算器,它有很多个功能。加减乘除取余乘方等,利用简单工厂模式,我们要设计一个计算类Operation,这个类里面包含什么成员和方法呢?
- 1.两个计算所用的数据A和B,并且定义为private类型。
- 2.Get和Set函数,为子类的求值做铺垫。
- 3.抽象函数,getResult函数,子类要实现它。
关于抽象类,有以下几点需要注意:
- 抽象类不可实例化,也就是不会直接去使用它,而是通过子类的继承间接使用。
- 抽象方法必须被子类重写,这里的getResult函数要被子类重写。
- 包含抽象方法的类要定义为抽象类。
三、普通代码实例
这个抽象类的代码如下:
package design;
public abstract class Operation {
private double numA = 0;
private double numB = 0;
public double getNumA() {
return numA;
}
public void setNumA(double numA) {
this.numA = numA;
}
public double getNumB() {
return numB;
}
public void setNumB(double numB) {
this.numB = numB;
}
public abstract double getResult();// 公共属性
}
有了这个抽象类,我们要设计加减乘除子类,子类继承这个抽象类并重写getResult方法。代码如下:
package design;
public class OperationAdd extends Operation {
@Override
public double getResult() {
// TODO Auto-generated method stub
double result=0;
result=getNumA()+getNumB();
return result;
}
}
package design;
public class OperationSub extends Operation {
@Override
public double getResult() {
// TODO Auto-generated method stub
double result=0;
result=getNumA()-getNumB();
return result;
}
}
package design;
public class OperationMul extends Operation {
@Override
public double getResult() {
// TODO Auto-generated method stub
double result=0;
result=getNumA()*getNumB();
return result;
}
}
package design;
public class OperationDiv extends Operation {
@Override
public double getResult() {
// TODO Auto-generated method stub
double result = 0;
try {
result = getNumA() / getNumB();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return result;
}
}
有了这四个运算子类,就很方便了,假如以后要增加运算,只用添加别的运算类并继承抽象类就好了。
下面是工厂类,工厂类需要注意两点:
- 1.有一个静态的方法,用来创建并返回对象。
- 2.函数利用字符串参数来进行。
代码如下:
package design;
public class OperationFactory {
public static Operation createOperation(String operate)
{
Operation ope=null;
switch(operate)
{
case "+":
ope=new OperationAdd();
break;
case "-":
ope=new OperationSub();
break;
case "*":
ope=new OperationMul();
break;
case "/":
ope=new OperationDiv();
break;
}
return ope;
}
}
建立完这个工厂类之后,我们就可以进行客户端的建立了,这里我们再添加一个测试类。
package design;
public class MainOne {
public static void main(String[] args) {
// TODO Auto-generated method stub
try
{
Operation ope;
ope = OperationFactory.createOperation("+");
ope.setNumA(100);
ope.setNumB(100);
double result = ope.getResult();
System.out.println(result);
}catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
通过这个测试类,我们可以对象创立并测试代码。
四、配置文件+反射
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SimpleFactory
{
public abstract class Operation
{
private double numA = 0;
private double numB = 0;
public double NumA
{
set { numA = value; }
get { return numA; }
}
public double NumB
{
set { numB = value; }
get { return numB; }
}
public abstract double getResult();// 公共属性
}
}
各种操作类和上面相同,不再写出。
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace SimpleFactory
{
class SuperFactory
{
private static readonly string AssemblyName = "SimpleFactory";
private static readonly string db = ConfigurationManager.AppSettings["Operation"];
public static Operation CreateFactory()
{
try
{
string className = AssemblyName + "." + db;
Console.WriteLine(className);
return (Operation)Assembly.Load(AssemblyName).CreateInstance(className);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return new OperationAdd();
}
}
}
}
这里利用配置文件+反射实现,去掉了Switch语句,实现了解耦。加上反射,就很完美了呀。
这里的反射要添加引用,在System下。然后是注意要用英文,中文会出现很多问题。
五、UML图
UML图如下:(很不专业的画法)