您的位置:首页 > 其它

23种设计模式学习之东拼西凑-------抽象工厂模式

2009-03-02 14:42 330 查看
我的理解就是给与最大的方便添加新的工厂。按照下面的内容进行抽象工厂模式分解创建。

抽象工厂(Abstract Factory)
声明生成一系列抽象产品的方法

具体工厂(Concrete Factory)
执行生成一系列抽象产品的方法,生成一系列具体的产品

抽象产品(Abstract Product)
为这一系列的某一种产品声明接口

具体产品(Product)
定义具体工厂生成的具体产品的对象,实现产品接口

客户(Client)
我们的应用程序客户端(不要理解成人),使用抽象产品和抽象工厂生成对象。

用网上搜到的代码案例进行学习理解:

中国企业需要一项简单的财务计算:每月月底,财务人员要计算员工的工资。
员工的工资 = (基本工资 + 奖金 - 个人所得税)。这是一个放之四海皆准的运算法则。
为了简化系统,我们假设员工基本工资总是4000美金。
中国企业奖金和个人所得税的计算规则是:
奖金 = 基本工资(4000) * 10%
个人所得税 = (基本工资 + 奖金) * 40%
我们现在要为此构建一个软件系统(代号叫Softo),满足中国企业的需求。
建立抽象工厂:

这个是常量

namespace AbstractFactory
{
/// <summary>
/// 公用的常量
/// </summary>
public class Constant
{
public static double BASE_SALARY = 4000;

}
}

抽象工厂:

namespace AbstractFactory
{
/// <summary>
/// Factory类
/// </summary>

public abstract class AbstractFactory
{
public static AbstractFactory GetInstance()
{
string factoryName = Constant.STR_FACTORYNAME.ToString();

AbstractFactory instance;

if(factoryName == "ChineseFactory")
instance = new ChineseFactory();
else if(factoryName == "AmericanFactory")
instance = new AmericanFactory();
else
instance = null;

return instance;
}

public abstract Tax CreateTax();

public abstract Bonus CreateBonus();
}
}

抽象产品(Abstract Product)

/// <summary>
/// 奖金抽象类
/// </summary>
public abstract class Bonus
{
public abstract double Calculate();
}

抽象产品(Abstract Product)

/// <summary>
/// 个人所得税抽象类
/// </summary>
public abstract class Tax
{
public abstract double Calculate();
}
}

配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="factoryName" value="AmericanFactory"></add>
</appSettings>
</configuration>

具体工厂:

1

namespace AbstractFactory
{
/// <summary>
/// ChineseFactory类
/// </summary>
public class ChineseFactory:AbstractFactory
{
public override Tax CreateTax()
{
return new ChineseTax();
}

public override Bonus CreateBonus()
{
return new ChineseBonus();
}
}
}

具体产品(Product)

/// <summary>
/// 计算中国个人奖金
/// </summary>
public class ChineseBonus:Bonus
{
public override double Calculate()
{
return Constant.BASE_SALARY * 0.1;
}
}

具体产品(Product)

/// <summary>
/// 计算中国个人所得税
/// </summary>
public class ChineseTax:Tax
{
public override double Calculate()
{
return (Constant.BASE_SALARY + (Constant.BASE_SALARY * 0.1)) * 0.5;
}
}

2.

namespace AbstractFactory
{
/// <summary>
/// AmericanFactory类
/// </summary>
public class AmericanFactory:AbstractFactory
{
public override Tax CreateTax()
{
return new AmericanTax();
}

public override Bonus CreateBonus()
{
return new AmericanBonus();
}
}
}

具体产品(Product)

/// <summary>
/// 计算美国个人所得税
/// </summary>
public class AmericanTax:Tax
{
public override double Calculate()
{
return (Constant.BASE_SALARY + (Constant.BASE_SALARY * 0.1)) * 0.4;
}
}

具体产品(Product)

/// <summary>
/// 计算美国奖金
/// </summary>
public class AmericanBonus:Bonus
{
public override double Calculate()
{
return Constant.BASE_SALARY * 0.1;
}
}

剩下的就是客户端了:

/// <summary>
/// 客户端程序调用
/// </summary>
public class Calculator
{
public static void Main(string[] args)
{
AmericanBonus bonus = new AmericanBonus();
double bonusValue = bonus.Calculate();

AmericanTax tax = new AmericanTax();
double taxValue = tax.Calculate();

double salary = 4000 + bonusValue - taxValue;

Console.WriteLine("American Salary is:" + salary);
Console.ReadLine();
}
}

这样就完成了抽象类的模式,似乎没什么优点。除了可以通过配文件控制产品之外。假若现在增加新的具体工厂类,发现还是需要修改抽象类。不过可以通过反射解决。

现在修改抽象类为反射机制:

/// <summary>
/// Factory类
/// </summary>
public abstract class AbstractFactory
{

public static AbstractFactory GetInstance()
{
string factoryName = Constant.STR_FACTORYNAME.ToString();

AbstractFactory instance;

if(factoryName != "")
instance = (AbstractFactory)Assembly.Load("AbstractFactory").CreateInstance("AbstractFactory." + factoryName);
else
instance = null;

return instance;
}

public abstract Tax CreateTax();

public abstract Bonus CreateBonus();
}

抽象产品与具体工厂等同上。

现在修改客户端:

/// <summary>
/// 客户端程序调用
/// </summary>
public class Calculator
{
public static void Main(string[] args)
{
AbstractFactory sds = AbstractFactory.GetInstance();
Bonus bonus = sds.CreateBonus();
double bonusValue = bonus.Calculate();

Tax tax = sds.CreateTax();
double taxValue = tax.Calculate();

double salary = 4000 + bonusValue - taxValue;

Console.WriteLine("Salary is:" + salary);
Console.ReadLine();
}
}

这样我们发现即使再增加新的系列产品,只需要继承抽象工厂实现具体工厂代码就可以了!

总结:

抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,运用抽象工厂模式的关键点在于应对“多系列对象创建”的需求变化
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: