书店会员销售系统(三)

书店会员销售系统(三)
                     ―― OO Refactoring and Design Pattern
本节目的:
1.         学习使用 Abstract Factory 模式。
2.         学习使用 Factory Method 模式。
3.         使用重构手法。

客户:  “你们前期的工作很不错,我们非常满意。”
项目经理:“谢谢你们的肯定。”
客户:   “不过打印的功能我想下个版本应该做好了吧?”
项目经理:“你们的打印是不是要支持屏幕打印和纸张打印两种模式?”
客户:    “Very Good!我就想这样做,你刚才不提醒我,我可能还忘了呢。”
项目经理:“好的,下个版本我们会实现这个功能的。”
    等客户走后,项目经理的脸沉了下来:“狡猾狡猾的,先表扬了一下,我看就没有好心肠,这不,活又来了。”然后径直向程序员走去。

   
客户就是上帝,这点我们不容怀疑。
    最苦的还是程序员,这点我们也不容怀疑。
    先来分析一下,这里有两种打印方式:POS机屏幕打印,纸张打印,理所当然要建一个抽象类,然后建两个子类。
    为了方便,我们这里只打印累计点数和金额。

   
    在main函数中加入以下代码:

    CPrint  * pPrint  =    new  CScreenPrint;
    
bool  bRel  =  pPrint -> Print(pMember -> GetPoint(),fConsumeSum);
    assert(bRel);

    delete pPrint;
    pPrint 
=   new  CPaperPrint;
    bRel 
=  pPrint -> Print(pMember -> GetPoint(),fConsumeSum);
    assert(bRel);
    delete pPrint;

   

class  CPrint  
{
public:
    
virtual ~CPrint();
    
virtual bool Print(int nPoint,float fSum) = 0;
}
;

   

CPaperPrint类代码如下:

class  CScreenPrint :  public  CPrint  
{
public:
    CScreenPrint();
    
~CScreenPrint();
     
bool Print(int nPoint,float fSum);
}
;

bool  CScreenPrint::Print( int  nPoint, float  fSum)
{
    printf(
"***Print on Screen:Point = %d, ConsumeSum =%f***/n",nPoint,fSum);
    
return TRUE;
}


   

编译通过,测试用例通过。
    程序运行的很好,没有新的需求,我们就让它这样吧,何必自寻烦恼呢?
    然而天下哪有这么好的事呢,过不了多久,客户就开始抱怨了:“我有两个分店,我想每个分店的打印格式不同。”
    不可否认,这确实是一个合理的要求,那就做吧,开始重构,使新功能更容易加入。
    首先进行改名,UML图如下:

class  CPaperPrint :  public  CPrint  
{
public:
    CPaperPrint();
    
~CPaperPrint();
    
bool Print(int nPoint,float fSum);
}


bool  CPaperPrint::Print( int  nPoint, float  fSum)
{
    printf(
"$$$Print on Paper:Point = %d, ConsumeSum =%f$$$/n",nPoint,fSum);
    
return TRUE;
}


   

   

    修改CScreenPrintShop1::Print函数为:

bool  CScreenPrintShop1::Print( int  nPoint, float  fSum)
{
    printf(
"***Shop 1 Print on Screen:Point = %d, ConsumeSum =%f***/n",nPoint,fSum);
    
return TRUE;
}

修改CPaperPrintShop1::Print函数为:

bool  CPaperPrintShop1::Print( int  nPoint, float  fSum)
{
    printf(
"$$$Shop 1 Print on Paper:Point = %d, ConsumeSum =%f$$$/n",nPoint,fSum);
    
return TRUE;
}

   

    
    代码我就不再贴了,和shop1差不多。把出现调用CPaperPrintShop1、CScreenPrintShop1的地方都修改为Shop2,编译通过,测试用例通过。
    马上有朋友会问了,这不是一个很明确的Factory Method设计模式吗?是的,这是Factory Method设计模式的应用,但我们只有在一处调用,何必麻烦去写Factory类呢?毕竟使用一些模式会增加好多的代码。
    记住一点:不一定用上设计模式才是完美的,实用才是硬道理。
    但正如你所说,随着需求的变化,程序中有两处或两处以上用到了打印的功能,那我们就必须修改了。UML图如下:

   

    不慌写代码,这里我们还能分析一下,Screen Print和Paper Print都会用到,为何我们不合并一下呢?UML图如下:

   

    这是一个什么模式啊?其实这是Abstract Factory的简化版。
    现在在一开始就初始化打印:

    CPrintFactory *   pPrintFactory  =   new  CShop1PrintFactory;

   

开始写代码吧,用在写代码的时间其实是比较少的,大多数的时间都是在设计和调试上,而调试的时间又占了大部分,我们要增加编程的效率,缩短调试的时间是最有效的,而建立测试用例就是一个很有效的方法。
    使用C++语言编写,在VC++ 6.0环境调试通过。
    代码下载
参考资料:
 Refactoring: Improving the Design of Existing Code》 ――Martin Fowler
 Design Patterns - Elements of Reusable Object-Oriented Software》 ――GoF

    CPrint  * pPrint  =   pPrintFactory -> CreateScreenPrint();
    
bool  bRel  =  pPrint -> Print(pMember -> GetPoint(),fConsumeSum);
    assert(bRel);

    delete pPrint;
    pPrint 
=  pPrintFactory -> CreatePaperPrint();
    bRel 
=  pPrint -> Print(pMember -> GetPoint(),fConsumeSum);
    assert(bRel);
    delete pPrint;

   

http://goodcandle.cnblogs.com/archive/2006/03/14/book3.html

然后在调用的地方写如下代码:
当然main函数中也要做相应地改动。
    编译通过,测试用例通过。
    现在可以增加shop 2了,UML图如下:
CScreenPrint类代码如下:
CPrint类代码如下:
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值