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();
}
}
这样我们发现即使再增加新的系列产品,只需要继承抽象工厂实现具体工厂代码就可以了!
总结:
抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,运用抽象工厂模式的关键点在于应对“多系列对象创建”的需求变化
抽象工厂(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();
}
}
这样我们发现即使再增加新的系列产品,只需要继承抽象工厂实现具体工厂代码就可以了!
总结:
抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,运用抽象工厂模式的关键点在于应对“多系列对象创建”的需求变化
相关文章推荐
- 23种设计模式学习之东拼西凑-------单例模式
- 23种设计模式学习之东拼西凑-------工厂方法模式
- 设计模式学习笔记(三)——Abstract Factory抽象工厂模式
- Java-马士兵设计模式学习笔记-工厂模式-抽象工厂模式
- java学习笔记-java开发中的23种设计模式
- 学习Java 23种设计模式详解笔记之创建型模式(一)
- 学习Java 23种设计模式详解笔记之行为型模式(三)
- 设计模式学习笔记(3) - 抽象工厂模式
- c++ 23种设计模式之抽象工厂模式
- 设计模式学习笔记——抽象工厂模式
- 23种设计模式(3):抽象工厂模式
- 23种设计模式之抽象工厂模式2
- php设计模式学习系列(四)--抽象工厂模式
- 设计模式学习---第九节:抽象工厂模式
- 23种设计模式学习—Prototype模式
- 学习Java 23种设计模式详解笔记之结构型模式(二)
- 23种设计模式[3]:抽象工厂模式
- java设计模式学习笔记--抽象工厂模式
- 设计模式学习笔记--23种设计模式(一)
- 23种设计模式(3):抽象工厂模式