Kĩ thuật lập trình - Chương 8: Tiến tới tư duy lập trình hướng đối tượng
Bạn đang xem 20 trang mẫu của tài liệu "Kĩ thuật lập trình - Chương 8: Tiến tới tư duy lập trình hướng đối tượng", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- ki_thuat_lap_trinh_chuong_8_tien_toi_tu_duy_lap_trinh_huong.pdf
Nội dung text: Kĩ thuật lập trình - Chương 8: Tiến tới tư duy lập trình hướng đối tượng
- Kỹ thuật lập trình ng 1 ươ 010101010101010110000101010101010101011000010101010101010101100001 Chương 8: TiếStateControllerntớ010101010010101010010101010101001010101001010101010100101010100101itư duy lậptrình start() 101001100011001001001010100110001100100100101010011000110010010010 Ch hướng ₫ốitượstop()ng110010110010001000001011001011001000100000101100101100100010000010 010101010101010110000101010101010101011000010101010101010101100001 010101010010101010010101010101001010101001010101010100101010100101 N Ơ 101001100011001001001010100110001100100100101010011000110010010010y = A*x + B*u; 110010110010001000001011001011001000100000101100101100100010000010x = C*x + d*u; LQGController010101010101010110000101010101010101011000010101010101010101100001 start() 010101010010101010010101010101001010101001010101010100101010100101 stop() 101001100011001001001010100110001100100100101010011000110010010010 110010110010001000001011001011001000100000101100101100100010000010 10/20/2005 2004, HOÀNG MINH S ©
- Nộidung chương 8 8.1 Đặtvấn ₫ề 8.2 Giớithiệuvídụ chương trình mô phỏng 8.3 Tư duy "rất" cổ₫iển 8.4 Tư duy hướng hàm 8.5 Tư duy dựatrên₫ốitượng (object-based) 8.6 Tư duy thựcsự hướng ₫ốitượng N Ơ Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 2 © 2005 - HMS ©
- 8.1 Đặtvấn ₫ề „Designing object-oriented software is hard, and designing reusable object-oriented software is even harder It takes a long time for novices to learn what object-oriented design is all about. Exprienced designers evidently know something inexperienced ones don't One thing expert designers know not to do is solve every problem from first principles. Rather, they reuse solutions that have worked for them in the past. When they find a good solution, they use it again and again. Such experience is part of what makes them experts. Consequently, you'll find recurring patterns of classes and communicating objects in many object-oriented systems. These patternsN solve specific design problems and make object-oriented designƠ more flexible, elegant, and ultimately reusable “ Erich Gamma et. al.: Design Patterns: Elements of Reusable Object- Oriented Software, Addison-Wesley, 1995. Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 3 © 2005 - HMS ©
- 8.2 Phầnmềmmôphỏng kiểuFBD 1(t) Sum StaticGain Limiter Integrator Scope Nhiệmvụ: Xây dựng phầnmềm ₫ể hỗ trợ mô phỏng thờigianthựcmột N cách linh hoạt, mềmdẻo, ₫áp ứng ₫ượccácyêucầucủatừng Ơ bài toán cụ thể Trướcmắtchưacầnhỗ trợ tạo ứng dụng kiểukéothả bằng công cụ₫ồhọa Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 4 © 2005 - HMS ©
- 8.3 Tư duy rấtcổ₫iển // SimProg1.cpp #include #include #include void main() { double K =1,I=0, Ti = 5; double Hi = 10, Lo = -10; double Ts = 0.5; double r =1, y=0, e, u, ub; cout << "u\ty"; while (!kbhit()) { e = r-y; // Sum block u = K*e; // Static Gain ub = max(min(u,Hi),Lo); // Limiter N I += ub*Ts/Ti; // Integrator state Ơ y = I; // Integrator output cout << '\n' << u << '\t' << y; cout.flush(); Sleep(long(Ts*1000)); } } Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 5 © 2005 - HMS ©
- Vấn ₫ề? Phầnmềmdướidạng chương trình, không có giá trị sử dụng lại Rấtkhóthay₫ổihoặcmở rộng theo yêu cầucụ thể củatừng bài toán Toàn bộ thuật toán ₫ược gói trong mộtchương trình => khótheodõi, dễ gây lỗi, không bảovệ₫ượcchất xám N Ơ Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 6 © 2005 - HMS ©
- 8.4 Tư duy hướng hàm // SimProg2.cpp #include #include #include #include "SimFun.h" void main() { double K = 5.0, double Ti = 5.0; double Hi = 10, Lo = -10; double Ts = 0.5; double r =1, y=0, e, u, ub; cout << "u\ty"; while (!kbhit()) { e = sum(r,-y); // Sum block u = gain(K,e); // Static Gain N ub= limit(Hi,Lo,u); // Limiter Ơ y = integrate(Ti,Ts,ub); // Integrator output cout << '\n' << u << '\t' << y; cout.flush(); Sleep(long(Ts*1000)); } } Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 7 © 2005 - HMS ©
- // SimFun.h inline double sum(double x1, double x2) { return x1 + x2; } inline double gain(double K, double x) { return K * x; } double limit(double Hi, double Lo, double x); double integrate(double Ti, double Ts, double x); // SimFun.cpp double limit(double Hi, double Lo, double x) { if (x > Hi) x = Hi; if (x < Lo) x = Lo; return x; } doubleN integrate(double Ti, double Ts, double x) { Ơ static double I = 0; I += x*Ts/Ti; return I; } Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 8 © 2005 - HMS ©
- Vấn ₫ề? Vẫnchưa ₫ủ tính linh hoạt, mềmdẻocầnthiết Thay ₫ổi, mở rộng chương trình mô phỏng rấtkhó khăn Các khâu có trạng thái như khâu tích phân, khâu trễ khó thựchiệnmộtcách"sạch sẽ" (trạng thái lưutrữ dướidạng nào?) Rấtkhópháttriển thành phầnmềmcóhỗ trợ₫ồhọa kiểukéothả N Ơ Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 9 © 2005 - HMS ©
- 8.5 Tư duy dựa ₫ốitượng // SimClass.h class Sum { public: double operator()(double x1, double x2) { return x1 + x2; } }; class Gain { double K; public: Gain(double k = 1) : K(k) {} double operator()(double x){ return K * x; } }; classN Limiter { Ơ double Hi, Lo; public: Limiter(double h=10.0, double l= -10.0); double operator()(double x); }; Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 10 © 2005 - HMS ©
- class Integrator { double Ki, Ts; double I; public: Integrator(double ti = 1.0, double ts = 0.5); double operator()(double x); }; class Delay { double* bufPtr; int bufSize; double Td, Ts; public: Delay(double td = 0, double ts = 1); Delay(const Delay&); Delay& operator=(Delay&); N Ơ ~Delay(); double operator()(double x); private: void createBuffer(int sz); }; Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 11 © 2005 - HMS ©
- #include #include "SimClass.h" Limiter::Limiter(double h, double l) : Hi(h), Lo(l) { if (Hi Hi) x = Hi; if (x 0) Ts = ts; if (ti > 0) Ki = ts/ti; N } Ơ double Integrator::operator()(double x) { I += x*Ki; return I; } Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 12 © 2005 - HMS ©
- Delay::Delay(double td, double ts) : Td(td), Ts(ts) { if (Td 0) { double y = bufPtr[0]; for (int i=0; i < bufSize-1; ++i) bufPtr[i] = bufPtr[i+1]; bufPtr[bufSize-1] = x; return y; } return x; } void Delay::createBuffer(int sz) { N Ơ bufSize = sz; bufPtr = new double[bufSize]; for (int i=0; i < bufSize; ++i) bufPtr[i] = 0.0; } Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 13 © 2005 - HMS ©
- // SimProg3.cpp #include #include #include #include "SimClass.h" void main() { double Ts = 0.5; Sum sum; Gain gain(2.0); Limiter limit(10,-10); Integrator integrate(5,Ts); Delay delay(1.0); double r =1, y=0, e, u, ub; cout << "u\ty"; while (!kbhit()) { e = sum(r,-y); // Sum block u = gain(e); // Static Gain ub= limit(u); // Limiter N Ơ y = integrate(ub);// Integrator output y = delay(y); cout << '\n' << u << '\t' << y; cout.flush(); Sleep(long(Ts*1000)); } } Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 14 © 2005 - HMS ©
- Vấn ₫ề? Khi số lượng các khốilớn lên thì quảnlýthế nào? Khi quan hệ giữacáckhốiphứctạphơn (nhiềuvào, nhiềura) thìtổ chứcquanhệ giữacác₫ốitượng như thế nào? Làm thế nào ₫ể tạovàquảnlýcác₫ốitượng mộtcách ₫ộng (trong lúc chương trình ₫ang chạy)? Lậptrìnhdựa ₫ốitượng mớimanglại ưu ₫iểmvề mặt an toàn, tin cậy, nhưng chưamanglại ưu ₫iểm về tính linh hoạtcầnthiếtcủaphầnmềm=> giátrị N Ơ sử dụng lạichưacao. Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 15 © 2005 - HMS ©
- 8.6 Tư duy hướng ₫ốitượng class FB { public: virtual void execute() = 0; private: virtual double* getOutputPort(int i=0) = 0; virtual void setInputPort(double* pFromOutputPort, int i=0)= 0; friend class FBD; }; Chiềudữ liệu px0 y0 px0 N px1 y0 Ơ px1=&y0 px2 y1 Chiều liên kết Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 16 © 2005 - HMS ©
- class Sum : public FB { public: Sum(bool plus_sign1 = true, bool plus_sign2 = false); void execute(); private: bool sign[2]; double *px[2]; double y; double* getOutputPort(int i=0); void setInputPort(double* pFromOutputPort, int i=0); }; Sum::Sum(bool plus_sign1, bool plus_sign2): y(0) { px[0] = px[1] = 0; sign[0] = plus_sign1; sign[1] = plus_sign2; } void Sum::execute() { if (px[0] != 0) y = sign[0] ? *(px[0]) : - *(px[0]); if (px[1] != 0) y += sign[1] ? *(px[1]) : - *(px[1]); N } Ơ double* Sum::getOutputPort(int) { return &y; } void Sum::setInputPort(double* pFromOutputPort, int i) { if(i < 2) px[i] = pFromOutputPort; Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng © 2005 - HMS 17 } ©
- class Limiter: public FB { public: Limiter(double h=10.0, double l = -10.0); void execute(); private: double Hi, Lo; double *px; double y; double* getOutputPort(int i=0); void setInputPort(double* pFromOutputPort, int i=0); }; Limiter::Limiter(double h, double l) : Hi(h), Lo(l), y(0), px(0) { if (Hi Hi) y = Hi; if (y < Lo) y = Lo; N } } Ơ double* Limiter::getOutputPort(int) { return &y; } void Limiter::setInputPort(double* pFromOutputPort, int i) { px = pFromOutputPort; }Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 18 © 2005 - HMS ©
- #include #include class FBD : public std::vector { double Ts; bool stopped; public: FBD(double ts = 0.5): Ts (ts > 0? ts : 1), stopped(true) {} void addFB(FB* p) { push_back(p); } void connect(int i1, int i2, int oport=0, int iport = 0) { FB *fb1= at(i1), *fb2= at(i2); fb2->setInputPort(fb1->getOutputPort(oport),iport); } void start(); ~FBD(); }; FBD::~FBD() { for (int i=0; i execute(); Sleep(long(Ts*1000)); } } Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 19 © 2005 - HMS ©
- #include #include "SimFB.h" void main() { double Ts=0.5; FBD fbd(0.5); fbd.addFB(new Step(1.0)); // 0 fbd.addFB(new Sum); // 1 fbd.addFB(new Gain(5.0)); // 2 fbd.addFB(new Limiter(10,-10)); // 3 fbd.addFB(new Integrator(5,Ts)); // 4 fbd.addFB(new Delay(0.0, Ts)); // 5 fbd.addFB(new Scope(std::cout)); // 6 for(int i=0; i < fbd.size()-1; ++i) fbd.connect(i,i+1); fbd.connect(5,1,0,1); N fbd.connect(3,6,0,1); Ơ std::cout << "y\tu"; fbd.start(); } Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 20 © 2005 - HMS ©
- Bài tậpvề nhà Luyệntậplại trên máy tính các ví dụ từ phần 8.3 — 8.5 Dựatrêncácvídụ lớp ₫ãxâydựng ở phần 8.6 (Limiter, Sum), bổ sung các lớpcònlại (Step, Scope, Gain, Integrator, Delay) Chạythử lạichương trình ở phần8.6 saukhi₫ãhoànthiệncác lớpcầnthiết. Bổ sung lớpPulse ₫ể mô phỏng tác ₫ộng của nhiễuquátrình (dạng xung vuông biên ₫ộ nhỏ, chu kỳ₫ặt ₫ược). Mở rộng chương trình mô phỏng như minh họatrênhìnhvẽ. Pulse N Ơ Step Sum Gain Limiter Integrator Delay Sum Scope Ch2004, HOÀNG MINH S ương 8: Tiếntớitư duy hướng đốitượng 21 © 2005 - HMS ©