论坛首页 Java企业应用论坛

java设计模式全解[2]-抽象工厂模式

浏览 5629 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-06-10  

 

抽象工厂模式(Abstract Factory) 

<o:p></o:p> 

本文参考Terrylee的博客 另外可参考lintomnywww.iteye.com/article/70952 的抽象工厂[他的代码相对我的更详细]

 概述
在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时由于需求的变化,往往存在着更多系列对象的创建工作。如何应对这种变化?如何绕过常规的对象的创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?这就是我们要说的抽象工厂模式。
意图
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
zmo_xu在这里,直接引用Terrylee给出的例子:这里我引用他的分析,然后给出代码,因为抽象工厂,说白了就是将很多相同的类的方法抽象到抽象类或者接口里面然后通过父类引用子类实例来实现,而这个回调在封装到一个工厂类里面[还是那句老话,大家一起讨论,共同进步,我有错的地方请一定告诉我]

虚拟案例<o:p></o:p>

中国企业需要一项简单的财务计算:每月月底,财务人员要计算员工的工资。<o:p></o:p>

员工的工资 = (基本工资 + 奖金 - 个人所得税)。这是一个放之四海皆准的运算法则。<o:p></o:p>

为了简化系统,我们假设员工基本工资总是4000美金。<o:p></o:p>

中国企业奖金和个人所得税的计算规则是:<o:p></o:p>

奖金 = 基本工资(4000) * 10%<o:p></o:p>

个人所得税 = (基本工资 + 奖金) * 40%<o:p></o:p>

我们现在要为此构建一个软件系统(代号叫Softo),满足中国企业的需求。<o:p></o:p>

案例分析<o:p></o:p>

奖金(Bonus)、个人所得税(Tax)的计算是Softo系统的业务规则(Service)<o:p></o:p>

工资的计算(Calculator)则调用业务规则(Service)来计算员工的实际工资。<o:p></o:p>

工资的计算作为业务规则的前端(或者客户端Client)将提供给最终使用该系统的用户(财务人员)使用。

现在又要将程序拿到美国使用 

针对美国企业为系统建模<o:p></o:p>

为了拓展国际市场,我们要把该系统移植给美国公司使用。<o:p></o:p>

美国企业的工资计算同样是: 员工的工资 = 基本工资 + 奖金 - 个人所得税。<o:p></o:p>

但是他们的奖金和个人所得税的计算规则不同于中国企业:<o:p></o:p>

美国企业奖金和个人所得税的计算规则是:<o:p></o:p>

        奖金 = 基本工资 * 15 %<o:p></o:p>

        个人所得税 = (基本工资 * 5% + 奖金 * 25%)   <o:p></o:p>

根据前面为中国企业建模经验,我们仅仅将ChineseTaxChineseBonus修改为AmericanTaxAmericanBonus

[不是太稳定提交保存下]

好现在给出代码:代码比较断就写在一个文件里面了

java 代码
  1. package zmo;   
  2.   
  3. public interface Tax   
  4. {   
  5.   
  6.     public double Calculate();   
  7. }   
  8.   
  9. //-----------------   
  10. package zmo;   
  11.   
  12. public interface Bonus   
  13. {   
  14.     public double Calculate();   
  15. }   
  16. //------------------   
  17. package zmo;   
  18.   
  19. public class ChineseBonus implements Bonus   
  20. {   
  21.   
  22.     public double Calculate()   
  23.     {   
  24.         return Constant.BASE_SALARY * 0.1;   
  25.     }   
  26.   
  27. }   
  28. //----------------------   
  29. package zmo;   
  30.   
  31. public class ChineseTax implements Tax   
  32. {   
  33.   
  34.     public double Calculate()   
  35.     {   
  36.         return (Constant.BASE_SALARY+Constant.BASE_SALARY*0.1) * 0.4;   
  37.     }   
  38. }   
  39. //--------------------------   
  40. package zmo;   
  41.   
  42. public class Constant   
  43. {   
  44.     public static double BASE_SALARY = 4000;   
  45. }   
  46. //--------------------------   
  47. package zmo;   
  48.   
  49. import zmo.ChineseBonus;   
  50. import zmo.ChineseTax;   
  51.   
  52.   
  53. public class Factory   
  54. {   
  55.     public Tax CreateTax()   
  56.     {   
  57.         return new ChineseTax();   
  58.     }   
  59.   
  60.     public Bonus CreateBonus()   
  61.     {   
  62.         return new ChineseBonus();   
  63.     }   
  64. }   
但是这样当我们要改变业务逻辑时 还是要修改工厂类来实现American 所以我们要请出今天的主角Class,呵呵,没有打错就是Class.zmo_xu在这里要使用Class的forname方法 先给出一段演示实例
java 代码
  1. package unit;   
  2.   
  3. public class Test   
  4. {   
  5.   
  6.     public void show()   
  7.     {   
  8.         System.out.println("看到这个输出表示你已经理解了反射机制");   
  9.     }   
  10. }   
  11. package unit;   
  12.   
  13. public class ClassShow   
  14. {   
  15.   
  16.     public static void main(String[] args)   
  17.     {   
  18.         try  
  19.         {   
  20.             Class ctx=Class.forName("unit.Test");   
  21.             Object o=ctx.newInstance();   
  22.             Test test=(Test)o;   
  23.             test.show();   
  24.         }   
  25.         catch (ClassNotFoundException e)   
  26.         {   
  27.             e.printStackTrace();   
  28.         }   
  29.         catch (InstantiationException e)   
  30.         {   
  31.             e.printStackTrace();   
  32.         }   
  33.         catch (IllegalAccessException e)   
  34.         {   
  35.             e.printStackTrace();   
  36.         }   
  37.     }   
  38. }   
最后就是用ResourceBundle来帮定资源文件 来实现Factory类这样就可以实现 不改源代码就能修改对应的实例 具体方法在builder  建造者模式里面再详细讲吧 ,那个好像不属于抽象工厂的范畴了
   发表时间:2007-06-11  
呵呵 这一篇就简单的讲讲 如果要深入了解 可以参见社区里面别的帖子 ,在这里给出这篇文章只是想人帖子看起来更系列一点
0 请登录后投票
   发表时间:2007-06-12  
哦,多么优雅的代码
0 请登录后投票
   发表时间:2007-07-18  
跑题了吧兄弟
0 请登录后投票
   发表时间:2007-07-18  
这是抽象工厂模式吗
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics