Re: 不懂如何抽离物件(初学物件导向的问题)

楼主: sunneo (艾斯寇德)   2008-09-02 17:48:50
其实你可以爬文看看之前的文章,大概都有写的很清楚,
除了封装可以把事情都包在一起外,重要的就是polymophism的地方,就是一个接口,
比如说程式码里面有好几个地方都长的很像,为了避免copy-paste之嫌,所以
把同样的部分抽出来成为caller,不同的部分成为abstract callee method.
然后之后的实作只是把callback的部分实体化。
caller就依照他预先想好的行为来叫用。
举个系统模拟的例子。
今天要实作算法,分别是First Come First Service,Shortest Job First,
Round Robin
刚开始的时候真的就一个一个写出来。
假设facility本身就会纪录进入时间以及离开时间,产生critical section
并且制作critirial report.
void fcfs(){
require(facility);
advance(time_slice);
release(facility);
}
void sjf(){ // Shortest Job First
set_priority(-time_slice);
require(facility);
advance(time_slice);
release(facility);
}
void rr(){ // Round Robin
double my_time = min(time_slice,std_time_slice);
for(;;){
require(facility);
advance(my_time);
time_slice -= my_time;
release(facility);
if(time_slice) yield();
else terminate();
}
}
这里知道Round Robin中间有部分不一样,其他都很像,于是改为
void rr_helper(){
time_slice -= my_time;
release(facility);
if(time_slice) yield();
else terminate();
}
void rr(){
for(;;){
require(facility);
double my_time = min(time_slice,std_time_slice);
advance(my_time);
release(facility);
rr_helper();
}
}
然后sjf只有刚开始设定优先权跟fcfs不一样,所以把设定优先权抽了出来
抽为init
所以sjf改为如下
void sjf(){
init();
require(facility);
advance(time_slice);
release(facility);
}
于是流程就变成如下,这时候fcfs已经可以跟sjf用下面的接口完成了。
void init(){
set_priority(-time_slice);
}
void sche_alg(){
init();
require(facility);
advance(time_slice);
release(facility);
}
然后为了rr可以同时使用,将time_slice改为my_time,用for(;;)包起流程
并且增加了一个get_new_time_slice();
将after_release加入
void rr::rr_helper(){
time_slice -= my_time;
release(facility);
if(time_slice) yield();
else terminate();
}
void fcfs::after_release(){
terminate();
}
void rr::after_release(){
rr_helper();
}
void sche_alg(){
init();
for(;;){
require(facility);
get_new_time_slice();
advance(my_time);
release(facility);
after_release();
}
}
终于完成了,可喜可贺...
以class来呈现就如下
class Schedule_Algorithm: public SLX::Puck{
protected:
double my_time,time_slice;
virtual after_release(){ terminate(); }
virtual void get_new_time_slice(){}
public:
FCFS(double tm_slice) :my_time(tm_slice),time_slice(tm_slice){}
virtual void action(){
for(;;){
require(facility);
get_new_time_slice();
advance(my_time);
release(facility);
after_release();
}
}
};
class FCFS: public Schedule_Algorithm {
public:
FCFS(double tm_slice): Schedule_Algorithm(tm_slice){}
};
class SJF: public FCFS{
public:
SJF(double tm_slice):FCFS(tm_slice){
set_priority(-tm_slice);
}
};
class RR: public FCFS{
enum rr_config{ std_time_slice=5 };
public:
virtual void after_release(){
time_slice -= my_time;
release(facility);
if(time_slice) yield();
else terminate();
}
RR(double tm_slice):FCFS(tm_slice){}
void get_new_time_slice(){
my_time = min(time_slice,(double)std_time_slice);
}
};
花了些时间,终于是都抽出来了,后来才发现抽出来实在没有必要。
因为他们都是算法,以后又多了算法,那么基本流程(action)还是得被改过一次.
所以可以先看看有没有必要抽离出来,否则作了也是浪费时间。

Links booklink

Contact Us: admin [ a t ] ucptt.com