Microsoft Word Bai 6 1 docx Trang 1 MÔN CÁC MẪU THIẾT KẾ HỚNG ỐI TỢNG Bài thực hành số 6 1 Xây dựng và kiểm thử hệ thống qun lý biểu thức I Mục tiêu Giúp SV làm quen với cách thức qun lý biểu t[.]
Trang MÔN : CÁC MẪU THIẾT KẾ HỚNG ỐI TỢNG Bài thực hành số 6.1 : Xây dựng kiểm thử hệ thống qun lý biểu thức I Mục tiêu : Giúp SV làm quen với cách thức qun lý biểu thức i số Giúp SV biết cách sử dụng mẫu thiết kế Singleton, Apdater, Composite, Abstract Factory yêu cầu cụ thể II Nội dung : Xây dựng module qun lý biểu thức i số nh sau : biểu thức ợc xây dựng phép tốn hai ngơi +, -, *, / Các biểu thức c bn thực hay biến thực biểu thức có dịch vụ thiết yếu : - tối gin - tính trị III Chuẩn ầu : Nắm vững tính chất, cơng dụng mẫu thiết kế Singleton, Adapter, Composite, Abstract Factory ể dùng li mẫu vị trí chng trình cần xây dựng IV Qui trình xây dựng chng trình Chy VS Net, chọn menu File.New.Project ể hiển thị cửa sổ New Project Mở rộng mục Visual C# TreeView "Project Types", chọn mục Window, chọn icon "Windows Form Application" listbox "Templates" bên phi, thiết lập th mục chứa Project listbox "Location", nhập tên Project vào textbox "Name:" (td BaiTH7), click button OK ể to Project theo thông số ã khai báo Form ầu tiên ứng dụng ã hiển thị cửa sổ thiết kế, việc thiết kế form trình lặp thao tác to mới/xóa/hiệu chỉnh thuộc tính/to hàm xử lý kiện cho ối tợng cần dùng form Ta s thiết kế form ứng dụng sau Bây ta xây dựng hệ thống chứa thành phần miêu t biểu thức to biểu thức Dời chuột gốc Project cửa sổ "Solution Explorer", ấn phi chuột phần tử gốc này, chọn option Add.New Folder, ặt tên cho folder Expression ể việc lấy số ngẫu nhiên nhiều phần tử phần mềm ợc quán, ta s to ối tợng chuyên phục vụ to số ngẫu nhiên ể bo m phần tử to số ngẫu nhiên nhất, ta dùng mẫu thiết kế Singleton Hãy thực ối tợng có dịch vụ sau : - to số nguyên ngẫu nhiên - to số nguyên ngẫu nhiên nằm khong từ tới n - to số thực ngẫu nhiên nằm khong từ tới Trang Dời chuột th mục Expression cửa sổ “Solution Explorer”, ấn phi chuột vào ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ “Add New Item”, chọn mục “Class”, hiệu chỉnh tên class MyRandom.cs, chọn button Add ể máy to class Viết code cho class nh sau : class MyRandom { //hàm khởi to private ể cấm bên to ối tợng MyRandom private MyRandom() { } //thông tin dùng chung class private static MyRandom myrnd = new MyRandom(); public static MyRandom getInstance() { return myrnd; } //thông tin ối tợng private Random rnd = new Random(); public int RndInt() { return rnd.Next(); } public int RndInt(int n) { return rnd.Next(n); } public double RndDouble() { return rnd.NextDouble(); } } Lu ý ta ã dùng mẫu Adapter ể xây dựng class MyRandom dựa class Random NET Class MyRandom giống y nh class MyRandom ã ợc viết th viện GenLib thực hành 5.1 ể qun lý biểu thức, ta dùng mẫu thiết kế Composite ể ịnh nghĩa thành phần cấu thành biểu thức theo lợc ồ class nh sau : Trớc hết, ịnh nghĩa interface chung cho biểu thức : hằng, biến, biểu thức ngơi có dịch vụ sau : - tham kho biểu thức bên trái - tham kho biểu thức bên phi - tính trị biểu thức - tối gin biểu thức Dời chuột th mục Expression cửa sổ “Solution Explorer”, ấn phi chuột vào ể hiển thị menu lệnh, chọn chức nng Add.New Item ể hiển thị cửa sổ “Add New Item”, chọn mục “Interface”, hiệu chỉnh tên interface IExpression.cs, chọn button Add ể máy to interface Viết code cho interface nh sau : interface IExpression { //hàm tính trị biểu thức double eval(IVarList e); //hàm tối gin biểu thức IExpression simplify(); //ịnh nghĩa thuộc tính Left (chỉ ọc) IExpression Left {get;} //ịnh nghĩa thuộc tính Right (chỉ ọc) IExpression Right { get; } } Trang Hiện thực class abstract chứa thông tin chung mà ối tợng biểu thức khác (hằng, biến, biểu thức ngơi) s dùng : - thuộc tính Left (vì biến khơng cần) - thuộc tính Right (vì biến khơng cần) Dời chuột th mục Expression cửa sổ “Solution Explorer”, ấn phi chuột vào ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ “Add New Item”, chọn mục “Class”, hiệu chỉnh tên class AbstractExpr.cs, chọn button Add ể máy to class Viết code cho class nh sau : abstract class AbstractExpr : IExpression { //hàm tính trị biểu thức public abstract double eval(IVarList e); //hàm tối gin biểu thức public abstract IExpression simplify(); //hiện thực thuộc tính Left (chỉ ọc) public virtual IExpression Left { get { return null; } } //hiện thực thuộc tính Right (chỉ ọc) public virtual IExpression Right { get { return null; } } } Hiện thực class miêu t số : Dời chuột th mục Expression cửa sổ “Solution Explorer”, ấn phi chuột vào ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ “Add New Item”, chọn mục “Class”, hiệu chỉnh tên class Constant.cs, chọn button Add ể máy to class Viết code cho class nh sau : class Constant : AbstractExpr { //giá trị private double value; //hàm khởi to có giá trị d xác ịnh public Constant(double d) { value = d; } //hàm tính tốn public override double eval(IVarList e) { return value; } //hiện thực thuộc tính Value (chỉ ọc) public double Value { get { return value; } } Trang //hàm gii mã chuỗi vn bn public override String ToString() { return String.Format("{0:f5}", value); } //hàm tối gin public override IExpression simplify() { //không thể tối gin hn return this; } } 10 Hiện thực class miêu t biến, ta dùng cách ặc tên biến theo dng Xi, với i số biến từ trở lên : Dời chuột th mục Expression cửa sổ “Solution Explorer”, ấn phi chuột vào ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ “Add New Item”, chọn mục “Class”, hiệu chỉnh tên class Variable.cs, chọn button Add ể máy to class Viết code cho class nh sau : class Variable : AbstractExpr { //chỉ số biến mơi trờng tính tốn private int rang; //hàm khởi to biến có số i public Variable(int i) { rang = i; } //hàm tính trị biến public override double eval(IVarList e) { return e[rang]; } //hàm gii mã biến thành dng chuỗi public override String ToString() { return "X" + rang; } //hàm tối gin biến public override IExpression simplify() { //không thể tối gin hn return this; } } 11 Hiện thực kiểu enum miêu t mã phép toán ợc dùng ể xây dựng biểu thức Trong thực hành ta hn chế dùng tốn tử ngơi cộng, trừ, nhân ể xây dựng biểu thức Ta không dùng phép chia ể hn chế lỗi chia q trình tính biểu thức : Trang Dời chuột th mục Expression cửa sổ “Solution Explorer”, ấn phi chuột vào ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ “Add New Item”, chọn mục “Class”, hiệu chỉnh tên class Operator.cs, chọn button Add ể máy to class Viết code cho class nh sau : enum Operator { //kiểu liệt kê mã phép tốn ngơi ợc dùng PLUS, MINUS, MULT, DIV } Lu ý phi ổi từ khóa từ class thành enum 12 Hiện thực class miêu t biểu thức dùng tốn tử ngơi : Dời chuột th mục Expression cửa sổ “Solution Explorer”, ấn phi chuột vào ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ “Add New Item”, chọn mục “Class”, hiệu chỉnh tên class BinOpExpr.cs, chọn button Add ể máy to class Viết code cho class nh sau : class BinOpExpr : AbstractExpr { // toán hng trái private IExpression left; // toán hng phi private IExpression right; //mã tốn tử ngơi private Operator op; //hàm khởi to biểu thức dùng toán tử ngơi op dùng tốn hng l r public BinOpExpr(Operator op, IExpression l, IExpression r) { this.op = op; left = l; right = r; } //hàm tính trị biểu thức public override double eval(IVarList e) { switch (op) { case Operator.PLUS: return left.eval(e) + right.eval(e); case Operator.MINUS: return left.eval(e) - right.eval(e); case Operator.MULT: return left.eval(e) * right.eval(e); case Operator.DIV: return left.eval(e) / right.eval(e); } return 0; } Trang //hiện thực thuộc tính Left (chỉ ọc) public override IExpression Left { get { return left; } } //hiện thực thuộc tính Right (chỉ ọc) public override IExpression Right { get { return right; } } //hàm gii mã biểu thức thành chuỗi vn bn public override String ToString() { StringBuilder ret = new StringBuilder("(" + left); switch (op) { case Operator.PLUS: ret.Append(" + "); break; case Operator.MINUS: ret.Append(" - "); break; case Operator.MULT: ret.Append(" * "); break; default: ret.Append(" / "); break; } ret.Append(right + ")"); return ret.ToString(); } //hàm tối gin biểu thức public override IExpression simplify() { //tối gin biểu thức bên trái IExpression ls = left.simplify(); //tối gin biểu thức bên phi IExpression rs = right.simplify(); IExpressionFactory ef = new ExpressionFactory(); if ((rs as Constant) == null || (ls as Constant) == null) return ef.createBinaryOp(op, ls, rs); //tính biểu thức double ketqua; double l = ls.eval(null); double r = rs.eval(null); switch (op) { case Operator.PLUS: Trang ketqua = l + r; break; case Operator.MINUS: ketqua = l - r; break; case Operator.MULT: ketqua = l * r; break; default: ketqua = l / r; break; } return ef.createConstant(ketqua); } } 13 Ta cần ối tợng chuyên qun lý giá trị biến ể phục vụ tính tốn biểu thức theo biến Trớc hết ta ịnh nghĩa interface tối thiểu cho ối tợng qun lý giá trị biến Dời chuột th mục Expression cửa sổ “Solution Explorer”, ấn phi chuột vào ể hiển thị menu lệnh, chọn chức nng Add.New Item ể hiển thị cửa sổ “Add New Item”, chọn mục “Interface”, hiệu chỉnh tên interface IVarList.cs, chọn button Add ể máy to interface Viết code cho interface nh sau : interface IVarList { //ịnh nghĩa indexer double this [int i] {get; set; } } 14 Hiện thực ối tợng qun lý trị biến nh sau : Dời chuột th mục Expression cửa sổ “Solution Explorer”, ấn phi chuột vào ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ “Add New Item”, chọn mục “Class”, hiệu chỉnh tên class VarList.cs, chọn button Add ể máy to class Viết code cho class nh sau : class VarList : IVarList { //danh sách trị biến private double[] variables; //hàm khởi to mơi trờng tính tốn có size biến public VarList (int size) { variables = new double[size]; } //ịnh nghĩa indexer qun lý biến public double this [int i] { get { return variables[i]; } set { variables[i] = value; } Trang } //hàm gii mã biểu thức thành chuỗi vn bn public override String ToString() { String buf="["; for (int i = 0; i < variables.Length; i++) if (i == 0) buf += String.Format("{0:f5}", this[i]); else buf += ", " + String.Format("{0:f5}", this[i]); buf += "]"; return buf; } } 15 Ta dùng mẫu Abstract Factory ể cung cấp dịch vụ to ối tợng mà chng trình ứng dụng dùng ối tợng Factory có kh nng nh sau : - to ợc ối tợng số - to ợc ối tợng biến - to ợc ối tợng biểu thức nhị phân - to ợc ối tợng biểu thức ngẫu nhiên - to ợc ối tợng biểu thức ngẫu nhiên có tối a maxprof cấp lồng - to ợc ối tợng qun lý trị biến ợc dùng ể tính biểu thức Dời chuột th mục Expression cửa sổ “Solution Explorer”, ấn phi chuột vào ể hiển thị menu lệnh, chọn chức nng Add.New Item ể hiển thị cửa sổ “Add New Item”, chọn mục “Interface”, hiệu chỉnh tên interface IExpressionFactory.cs, chọn button Add ể máy to interface Viết code cho interface nh sau : interface IExpressionFactory { //hàm to có giá trị xác ịnh IExpression createConstant(double constant); //hàm to biến có số xác ịnh IExpression createVariable(int id); //hàm to biểu thức dùng tốn tử ngơi IExpression createBinaryOp(Operator op, IExpression left, IExpression right); //hàm to biểu thức ngẫu nhiên IExpression createRandomExpression(); //hàm to biểu thức ngẫu nhiên có tối a maxProf cấp IExpression createRandomExpression(int maxProf); //hàm to ối tợng tính tốn ngẫu nhiên IVarList createRandomVarList(); } Dời chuột th mục Expression cửa sổ “Solution Explorer”, ấn phi chuột vào ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ “Add New Item”, chọn mục “Class”, hiệu chỉnh tên class Trang ExpressionFactory.cs, chọn button Add ể máy to class Viết code cho class nh sau : class ExpressionFactory : IExpressionFactory { //số biến ợc dùng biểu thức private static int MAXVARIABLE = 2; //ối tợng to số ngẫu nhiên dng Singleton private MyRandom rnd = MyRandom.getInstance(); //hàm to biểu thức dùng tốn tử ngơi public IExpression createBinaryOp(Operator op, IExpression left, IExpression right) { return new BinOpExpr(op, left, right); } //hàm to có giá trị xác ịnh public IExpression createConstant(double constant) { return new Constant(constant); } //hàm to biến có số xác ịnh public IExpression createVariable(int id) { if (id >= MAXVARIABLE) MAXVARIABLE = id + 1; return new Variable(id); } //hàm to biểu thức ngẫu nhiên (có tối a cấp lồng nhau) public IExpression createRandomExpression() { return createRandomExpression(3); } //hàm to biểu thức ngẫu nhiên có tối a maxProf cấp lồng public IExpression createRandomExpression(int maxProf) { int cat=0; if (maxProf == 0) cat = rnd.RndInt(2); else cat = rnd.RndInt(4); switch (cat) { case 0: //biểu thức return createConstant(rnd.RndDouble()); case 1: // biểu thức biến return createVariable(rnd.RndInt(MAXVARIABLE)); } // biểu thức //to biểu thức bên trái IExpression left = createRandomExpression(maxProf - 1); Trang 10 //to biểu thức bên phi IExpression right = createRandomExpression(maxProf - 1); //to biểu thức return createBinaryOp((Operator)(rnd.RndInt(3)), left, right); } //hàm to ối tợng tính tốn ngẫu nhiên public IVarList createRandomVarList() { IVarList e = new VarList(MAXVARIABLE); for (int i = 0; i < MAXVARIABLE; i++) { e[i] = rnd.RndDouble(); } return e; } } 16 Duyệt tìm phần tử Form1 cửa sổ "Solution Explorer", ấn phi chuột vào mục này, chọn option "View Designer" ể hiển thị cửa sổ thiết kế Form1 17 Nếu cửa sổ ToolBox cha hiển thị chi tiết, chọn menu View.Toolbox ể hiển thị (thờng nằm bên trái hình) Click chuột vào button (Auto Hide) nằm góc phi cửa sổ ToolBox ể chuyển chế ộ hiển thị thờng trực 18 Duyệt tìm phần tử Button cửa sổ ToolBox, chọn v góc trái Form Vào cửa sổ thuộc tính Button hiệu chỉnh li thuộc tính Text = "Start", thuộc tính (Name) = btnStart To hàm xử lý kiện Click Button viết on code kiểm thử hệ thống qun lý biểu thức nh sau : private void btnStart_Click(object sender, EventArgs e){ //to ối tợng qun lý file ể ghi liệu StreamWriter oFile = new StreamWriter("data.txt", true, Encoding.Unicode); //to ối tợng Factory qun lý việc to biểu thức IExpressionFactory ef = new ExpressionFactory(); //to biểu thức ngẫu nhiên có tối a cấp lồng IExpression e1 = ef.createRandomExpression(6); //to danh sách giá trị biến ợc dùng tính tốn biểu thức IVarList env = ef.createRandomVarList(); oFile.WriteLine("Dùng danh sách giá trị biến : "+ env.ToString()); oFile.WriteLine("ể tính biểu thức:"); oFile.WriteLine(e1.ToString()); oFile.WriteLine(String.Format("Kết qu : {0:f5}", e1.eval(env))); oFile.WriteLine("Biểu thức có dng tối gin sau :"); e1 = e1.simplify(); oFile.WriteLine(e1.ToString()); oFile.WriteLine(String.Format("Kết qu tính : {0:f5}", e1.eval(env))); oFile.WriteLine("==============================================="); oFile.Close(); } Trang 11 Lu ý thêm lệnh using namespace ợc dùng ứng dụng nh sau : using System.IO; using BaiTH7.Expression; 19 Dịch chy chng trình Nếu có lỗi sửa, hết lỗi chng trình s chy Mỗi lần ngời dùng click chuột vào button, chng trình s to biểu thức ngẫu nhiên, tính xuất kết qu Sau ó, chng trình tối gin biểu thức, tính trị xuất kết qu ể so sánh Thử click chuột vào button nhiều lần (30 lần) dừng chng trình 20 Dùng trình WordPad mở file data.txt th mục chứa file kh thi chng trình, quan sát xem biểu thức ợc to xử lý bở chng trình xem có sai sót khơng ? ... Factory có kh nng nh sau : - to ợc ối tợng số - to ợc ối tợng biến - to ợc ối tợng biểu thức nhị phân - to ợc ối tợng biểu thức ngẫu nhiên - to ợc ối tợng biểu thức... biểu thức : hằng, biến, biểu thức ngơi có dịch vụ sau : - tham kho biểu thức bên trái - tham kho biểu thức bên phi - tính trị biểu thức - tối gin biểu thức Dời chuột th mục Expression cửa... tin chung mà ối tợng biểu thức khác (hằng, biến, biểu thức ngôi) s dùng : - thuộc tính Left (vì biến khơng cần) - thuộc tính Right (vì biến khơng cần) Dời chuột th mục Expression cửa sổ “Solution