在软件设计当中,有时我们可以遇到这种情况:我们需要确定的相互协作的两个类在行为上相互影响,就像学习和恋爱或者学习和应用一样,一方改变的时候,另一方的状态随之改变;然而另一方改变的时候,又反过来作用于原方。就像物理当中的速度和加速度一样。这个时候,我们应该怎样来明确我们的代码呢-------于是引出我们这里即将论述的学以致用模式。
学以致用模式是相互协作、相辅相成的两个类及多个对象之间的一种简约的表示。然而,他们之间的相互作用并不总是永远进行下去的,为了表示每次迭代作用方给被作用方的影响的程度,我们引入一个Progress,用以抽象这个进度,当进度结束的时候,这个迭代过程就终止了,因为这个时候两个相关的类以及多个对象之间的相互作用已经趋于饱和。类Learn和类Apply是相互作用、相互影响的两个类。
以下分别是上述模式的C++以及JAVA源代码。
C++:
//LearnAndApply.h
//CopyRight@Reserved
//2010-06-07
//Writer:redand_007black@163.com
#ifndef LEARN_AND_APPLLY_H__
#define LEARN_AND_APPLY_H__
class Progress;
class Learn;
class Apply;
class Progress
{
potected:
Progress();
virtual ~Progress();
public:
virtual bool IsOver()=0;
virtual void Step()=0;
virtual int /*可以是float如在0.0-1.0之间,与int在0与100之间*/ Current()=0;
};
class Learn
{
public:
Learn();
virtual ~Learn();
virtual void learn();
void addApply(Apply*);
void removeApply(Apply*);
bool IsOver();
private:
Progress *prg;
List<Apply*> *applys;
};
class Apply
{
public:
virtual void apply();
void addLearn(Learn*);
void removeLearn(Learn*);
bool IsOver();
private:
Progress *prg;
List<Learn*> *learns;
};
class ConcretProgress:public Progress
{
private:
int tick;
public:
ConcretProgress();
~ConcretProgress();
bool IsOver();
void Step();
int Current();
};
class EmptyProgress:public Progress
{
public:
bool IsOver(){return true;}
void Step(){}
int Current (){return 100;}
};
#endif
//LearnAndApply.cpp
//CopyRight@Reserved
//2010-06-07
//Writer:redand_007black@163.com
#include"LearnAndApply.h"
#include<iostream.h>
Progress::Progress (){}
Progress::~Progress(){}
Learn::Learn()
{
prg=new ConcretProgress();
applys=new List<Apply*>;
}
Learn::~Learn()
{
if(0!=prg)
delete prg;
prg=0;
if(0!=applys)
delete applys;
applys=0;
}
void Learn::learn()
{
if(!IsOver())
{
prg->Step();
cout<<"Learning..."<<endl;
}
ListIterator *li=learns.CreateIterator();
for(Learn*l=li->First();li->HasNext();l=li->Next())
l->apply();
delete li;
li=0;
}
inline void Learn::addApply(Apply*a)
{
applys->add(a);
}
inline void Learn::removeApply(Apply*a)
{
applys->remove(a);
}
inline bool Learn::IsOver
{
try
{
return prg->IsOver();
}
catch(...)
{
return true;
}
}
Apply::Apply()
{
prg=new ConcretProgress;
learns=new List<Learn*>;
}
Apply::~Apply()
{
if(0!=prg)
delete prg;
prg=0;
if(0!=learns)
delete learns;
learns=0;
}
inline void Apply::addLearn(Learn*l)
{
learns->add(l);
}
inline void Apply::removeLearn(Learn*l)
{
learns->remove(l);
}
inline bool Apply::IsOver()
{
if(0!=prg)
return prg->IsOver();
return true;
}
void Apply::apply()
{
if(!IsOver())
{
prg->Step();
cout<<"Applying..."<<endl;
}
ListIterator *li=applys.CreateIterator();
for(Apply*a=li->First();li->HasNext();a=li->Next())
a->apply();
delete li;
li=0;
}
//AutoPtr.h
#ifndef AUTOPTR_H__
#define AUTOPTR_H__
template<class T>
class AutoPtr
{
private:
T*delegate;
public:
AutoPtr(T*ptr)
{
delegate=ptr;
}
~AutoPtr()
{
if(0!=delegate)
delete delegate;
delegate=0;
}
T*getPtr(){return delegate;}
};
#endif
//Demo
//main.cpp
//Writer:redand_007black@163.com
#include"LearnAndApply.h"
#include"AutoPtr.h"
int main()
{
Learn *l1;
Learn*l2;
Apply *a1;
Apply*a2;
AutoPtr x1(l1=new Learn());
AutoPtr x2(l2=new Learn());
AutoPtr x3(a1=new Apply());
AutoPtr x4(a2=new Apply());
l1->addApply(a1);
l2->addApply(a2);
a1->addLearn(l2);
a2->addLearn(l1);
l1->learn();
a2->apply();
return 0;
}