Bài tập thực hành 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 quản lý biểu thức
Trang 1
MÔN : CÁC MẪU THIẾT KẾ HỚNG ỐI TỢNG
Bài thực hành số .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 thức i số. Giúp SV biết cách
sử dụng các mẫu thiết kế Singleton, Apdater, Composite, Abstract Factory
trong từng 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 :
1. biểu thức ợc xây dựng trên 4 phép toán hai ngôi +, -, *, /. Các biểu thức c
bn có thể là hằng thực hay biến thực.
2. mỗi biểu thức có 2 dịch vụ thiết yếu :
-
-
tối gin mình.
tính trị của mình.
III. Chuẩn ầu ra :
. Nắm vững tính chất, công dụng của các mẫu thiết kế Singleton, Adapter,
Composite, Abstract Factory ể có thể dùng li các mẫu này trong bất kỳ vị
trí nào của chng trình mới cần xây dựng.
IV. Qui trình xây dựng chng trình
1. Chy VS .Net, chọn menu File.New.Project ể hiển thị cửa sổ New Project.
2. Mở rộng mục Visual C# trong TreeView "Project Types", chọn mục Window,
chọn icon "Windows Form Application" trong listbox "Templates" bên phi,
thiết lập th mục chứa Project trong listbox "Location", nhập tên Project vào
textbox "Name:" (td. BaiTH ), click button OK ể to Project theo các thông
số ã khai báo.
3. Form ầu tiên của ứng dụng ã hiển thị trong cửa sổ thiết kế, việc thiết kế
form là quá trình lặp 4 thao tác to mới/xóa/hiệu chỉnh thuộc tính/to hàm
xử lý sự kiện cho từng ối tợng cần dùng trong form. Ta s thiết kế form ứng
dụng sau. Bây giờ ta xây dựng hệ thống con chứa các thành phần miêu t biểu
thức và to biểu thức.
4. Dời chuột về gốc cây Project trong cửa sổ "Solution xplorer", ấn phi chuột
trên phần tử gốc này, chọn option Add.New Folder, ặt tên cho folder mới là
xpression.
.
ể việc lấy số ngẫu nhiên của nhiều phần tử trong phần mềm ợc nhất quán,
ta s to 1 ối tợng duy nhất chuyên phục vụ to số ngẫu nhiên. ể bo m
phần tử to số ngẫu nhiên là duy nhất, ta dùng mẫu thiết kế Singleton. Hãy
hiện thực ối tợng này có các dịch vụ sau :
- to số nguyên ngẫu nhiên bất kỳ.
- to số nguyên ngẫu nhiên nằm trong khong từ 0 tới n.
- to số thực ngẫu nhiên nằm trong khong từ 0 tới 1.
Trang 2
Dời chuột về th mục xpression trong cửa sổ “Solution xplorer”, ấn phi
chuột vào nó ể 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 là
MyRandom.cs, chọn button Add ể máy to 1 class mới. Viết code cho class
này nh sau :
class MyRandom {
//hàm khởi to private ể cấm bên ngoài to ối tợng MyRandom
private MyRandom() { }
//thông tin dùng chung trong class
private static MyRandom myrnd = new MyRandom();
public static MyRandom getInstance() { return myrnd; }
//thông tin trong ố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 ý rằng ta ã dùng mẫu Adapter ể xây dựng class MyRandom dựa trên
class Random của .N T. Class MyRandom ở bài này cũng giống y nh class
MyRandom ã ợc viết trong th viện GenLib ở bài thực hành .1.
.
.
ể qun lý biểu thức, ta dùng mẫu thiết kế Composite ể ịnh nghĩa các
thành phần cấu thành biểu thức bất kỳ theo lợc ồ class nh sau :
Trớc hết, ịnh nghĩa interface chung cho các biểu thức : hằng, biến, biểu
thức 2 ngôi có các dịch vụ sau :
- tham kho biểu thức con bên trái.
- tham kho biểu thức con bên phi.
- tính trị biểu thức.
- tối gin biểu thức.
Dời chuột về th mục xpression trong cửa sổ “Solution xplorer”, ấn phi
chuột vào nó ể 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 là
I xpression.cs, chọn button Add ể máy to 1 interface mới. Viết code cho
interface này 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 3
8. Hiện thực class abstract chứa những thông tin chung mà các ối tợng biểu
thức khác nhau (hằng, biến, biểu thức 2 ngôi) s dùng :
- thuộc tính Left (vì hằng và biến không cần).
- thuộc tính Right (vì hằng và biến không cần).
Dời chuột về th mục xpression trong cửa sổ “Solution xplorer”, ấn phi
chuột vào nó ể 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 là
Abstract xpr.cs, chọn button Add ể máy to 1 class mới. Viết code cho class
này 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 hằng số :
Dời chuột về th mục xpression trong cửa sổ “Solution xplorer”, ấn phi
chuột vào nó ể 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 là Constant.cs,
chọn button Add ể máy to 1 class mới. Viết code cho class này nh sau :
class Constant : AbstractExpr {
//giá trị của hằng
private double value;
//hàm khởi to hằng có giá trị d xác ịnh
public Constant(double d) {
value = d;
}
//hàm tính toán hằng
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 4
//hàm gii mã hằng về chuỗi vn bn
public override String ToString() {
return String.Format("{0:f }", value);
}
//hàm tối gin hằng
public override IExpression simplify() {
//không thể tối gin hn nữa
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 là
chỉ số của biến từ 0 trở lên :
Dời chuột về th mục xpression trong cửa sổ “Solution xplorer”, ấn phi
chuột vào nó ể 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 là Variable.cs,
chọn button Add ể máy to 1 class mới. Viết code cho class này nh sau :
class Variable : AbstractExpr {
//chỉ số của biến trong môi trờng tính toán
private int rang;
//hàm khởi to biến có chỉ số i
public Variable(int i) {
rang = i;
}
//hàm tính trị của 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 nữa
return this;
}
}
11. Hiện thực kiểu enum miêu t mã các phép toán ợc dùng ể xây dựng biểu
thức. Trong bài thực hành này ta hn chế chỉ dùng 3 toán tử 2 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 0
trong quá trình tính biểu thức :
Trang 5
Dời chuột về th mục xpression trong cửa sổ “Solution xplorer”, ấn phi
chuột vào nó ể 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 là Operator.cs,
chọn button Add ể máy to 1 class mới. Viết code cho class này nh sau :
enum Operator {
//kiểu liệt kê các mã phép toán 2 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 toán tử 2 ngôi :
Dời chuột về th mục xpression trong cửa sổ “Solution xplorer”, ấn phi
chuột vào nó ể 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 là
BinOp xpr.cs, chọn button Add ể máy to 1 class mới. Viết code cho class
này nh sau :
class BinOpExpr : AbstractExpr {
// toán hng trái
private IExpression left;
// toán hng phi
private IExpression right;
//mã toán tử 2 ngôi
private Operator op;
//hàm khởi to biểu thức dùng toán tử 2 ngôi op dùng 2 toán hng l và r
public BinOpExpr(Operator op, IExpression l, IExpression r) {
this.op = op;
left = l;
right = r;
}
//hàm tính trị của 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 6
//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 con bên trái
IExpression ls = left.simplify();
//tối gin biểu thức con 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 hằng
double ketqua;
double l = ls.eval(null);
double r = rs.eval(null);
switch (op) {
case Operator.PLUS:
Trang 7
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ị của các biến ể phục vụ tính toán biểu
thức theo các biến. Trớc hết ta ịnh nghĩa interface tối thiểu cho ối tợng
qun lý giá trị của các biến này.
Dời chuột về th mục xpression trong cửa sổ “Solution xplorer”, ấn phi
chuột vào nó ể 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 là
IVarList.cs, chọn button Add ể máy to 1 interface mới. Viết code cho
interface này 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ị các biến nh sau :
Dời chuột về th mục xpression trong cửa sổ “Solution xplorer”, ấn phi
chuột vào nó ể 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 là VarList.cs,
chọn button Add ể máy to 1 class mới. Viết code cho class này nh sau :
class VarList : IVarList {
//danh sách trị của các biến
private double[] variables;
//hàm khởi to môi trờng tính toán có size biến
public VarList (int size) {
variables = new double[size];
}
//ịnh nghĩa indexer qun lý các biến
public double this [int i] {
get { return variables[i]; }
set { variables[i] = value; }
Trang 8
}
//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:f }", this[i]);
else buf += ", " + String.Format("{0:f }", this[i]);
buf += "]";
return buf;
}
}
1 . Ta dùng mẫu Abstract Factory ể cung cấp dịch vụ to các ố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 hằ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 nhau.
- to ợc ối tợng qun lý trị các biến ợc dùng ể tính biểu thức.
Dời chuột về th mục xpression trong cửa sổ “Solution xplorer”, ấn phi
chuột vào nó ể 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 là
I xpressionFactory.cs, chọn button Add ể máy to 1 interface mới. Viết code
cho interface này nh sau :
interface IExpressionFactory {
//hàm to hằng có giá trị xác ịnh
IExpression createConstant(double constant);
//hàm to biến có chỉ số xác ịnh
IExpression createVariable(int id);
//hàm to biểu thức dùng toán tử 2 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 toán ngẫu nhiên
IVarList createRandomVarList();
}
Dời chuột về th mục xpression trong cửa sổ “Solution xplorer”, ấn phi
chuột vào nó ể 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 là
Trang 9
xpressionFactory.cs, chọn button Add ể máy to 1 class mới. Viết code cho
class này nh sau :
class ExpressionFactory : IExpressionFactory {
//số biến ợc dùng trong biểu thức
private static int MAXVARIABLE = 2;
//ối tợng to số ngẫu nhiên duy nhất dng Singleton
private MyRandom rnd = MyRandom.getInstance();
//hàm to biểu thức dùng toán tử 2 ngôi
public IExpression createBinaryOp(Operator op, IExpression left, IExpression right) {
return new BinOpExpr(op, left, right);
}
//hàm to hằng có giá trị xác ịnh
public IExpression createConstant(double constant) {
return new Constant(constant);
}
//hàm to biến có chỉ 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 3 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 nhau
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 hằng
return createConstant(rnd.RndDouble());
case 1: // biểu thức biến
return createVariable(rnd.RndInt(MAXVARIABLE));
}
// biểu thức 2 ngôi
//to biểu thức con bên trái
IExpression left = createRandomExpression(maxProf - 1);
Trang 10
//to biểu thức con bên phi
IExpression right = createRandomExpression(maxProf - 1);
//to biểu thức 2 ngôi
return createBinaryOp((Operator)(rnd.RndInt(3)), left, right);
}
//hàm to ối tợng tính toá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;
}
}
1 . Duyệt tìm phần tử Form1 trong cửa sổ "Solution xplorer", ấ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.
1 . Nếu cửa sổ ToolBox cha hiển thị chi tiết, chọn menu View.Toolbox ể hiển
thị nó (thờng nằm ở bên trái màn hình). Click chuột vào button
(Auto
Hide) nằm ở góc trên phi cửa sổ ToolBox ể chuyển nó về chế ộ hiển thị
thờng trực.
18. Duyệt tìm phần tử Button trong cửa sổ ToolBox, chọn nó và v nó ở góc trên
trái của Form. Vào cửa sổ thuộc tính của Button và hiệu chỉnh li thuộc tính
Text = "Start", thuộc tính (Name) = btnStart. To hàm xử lý sự kiện Click
trên Button rồi 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 dữ liệu
StreamWriter oFile = new StreamWriter("data.txt", true, Encoding.Unicode);
//to ối tợng Factory qun lý việc to các biểu thức
IExpressionFactory ef = new ExpressionFactory();
//to biểu thức ngẫu nhiên có tối a 6 cấp lồng nhau
IExpression e1 = ef.createRandomExpression(6);
//to danh sách giá trị các biến ợc dùng trong tính toán biểu thức
IVarList env = ef.createRandomVarList();
oFile.WriteLine("Dùng danh sách giá trị các biến : "+ env.ToString());
oFile.WriteLine("ể tính biểu thức:");
oFile.WriteLine(e1.ToString());
oFile.WriteLine(String.Format("Kết qu là : {0:f }", 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 là : {0:f }", e1.eval(env)));
oFile.WriteLine("===============================================");
oFile.Close();
}
Trang 11
Lu ý thêm 2 lệnh using 2 namespace ợc dùng trong ứng dụng nh sau :
using System.IO;
using BaiTH .Expression;
1 . Dịch và chy chng trình. Nếu có lỗi thì sửa, nếu hết lỗi thì chng trình s
chy. Mỗi lần ngời dùng click chuột vào button, chng trình s to 1 biểu
thức ngẫu nhiên, tính và xuất kết qu. Sau ó, chng trình tối gin biểu
thức, tính trị và xuất kết qu ể so sánh. Thử click chuột vào button nhiều lần
(30 lần) rồi dừng chng trình.
20. Dùng trình WordPad mở file data.txt trong th mục chứa file kh thi của
chng trình, quan sát xem từng biểu thức ợc to ra và xử lý bở chng
trình xem có sai sót gì không ?
Bạn đang xem tài liệu "Bài tập thực hành 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 quản lý biểu thức", để tải tài liệu gốc về máy hãy click vào nút Download ở trên
File đính kèm:
bai_tap_thuc_hanh_mon_cac_mau_thiet_ke_huong_doi_tuong_bai_t.pdf

