Mẫu thiết kế Composite

Em chào các sư huynh ạ :smiley:
Em đang tìm hiểu vài bài tập về mẫu thiết kế Composite.
Và có 1 bài tập sau:
cho Folder1 có 2 file abc.txt, def.txt và 1 Folder2
Trong Folder2 có 2 file abc.txt và abc.exe

Sử dụng mẫu Composite để đếm số lượng file có tên “abc.txt”
Code của em ở dưới: Và em đang bí cách giải quyết quá :’(
Sư huynh nào có thể giúp em với ạ :’(
Em xin chân thành cảm ơn.

#include <iostream>
#include <conio.h>
#include <string>
#include <vector>

using namespace std;

class Item
{
public:
	string ten;
	Item(string ten)
	{
		this -> ten = ten;
	}

	virtual string what() { return ""; }
};

class File : public Item
{
public:
	File(string ten) : Item(ten) {}

	string what()
	{
		return "File";
	}
};


class Folder : public Item
{
protected:
	vector <Item*> dsItemCon;

public:
	Folder(string ten) : Item(ten) {}

	string what()
	{
		return "Folder";
	}

	const int DemTep(string s) const
	{
		int dem = 0;

		for(int i = 0; i < dsItemCon.size(); i++)
		{
			if(dsItemCon[i]-> ten == s && dsItemCon[i] -> what() == "File")
				dem++;
		}

		return dem;
	}

	void Add(Item *item)
	{
		dsItemCon.push_back(item);
	}
};

int main()
{
	File f1("abc.txt"), f2("abc.txt"), f3("haha.exe"), f4("def.txt");
	Folder folder1("Folder1"), folder2("Folder2");

	folder1.Add(&folder2);
	folder1.Add(&f1);
	folder1.Add(&f4);

	folder2.Add(&f2);
	folder2.Add(&f3);

	cout << "Folder 1 co " << folder1.DemTep("abc.txt") << " tep abc.txt";

	getch();
	return 0;
}

Vấn đề của bạn là gì? Bạn nên đặt tên method có ý nghĩa chút, what() là cái gì, thay bằng getType có phải dễ hiểu hơn không.
Ngoài ra chỉ có 2 loại là file hoặc folder thôi nên không cần thiết phải có 1 base class là item đâu, folder cũng là file mà

1 Like

Hi Nguyễn Tuấn Namnguyentuannam
Đây là code của mình. Mình đang phân vân có nên cho phương thức tim vào folder không.

#include <iostream>
#include <string>
#include <vector>

using namespace std;

typedef enum ITEM_TYPE {TYPE_FILE = 0, TYPE_FOLDER = 1} ITEM_TYPE;

class Item {
public:
	Item(string name, ITEM_TYPE type) : name(name), type(type) {
		//TODO
	}
	
	string getName(void) {
		return this->name;
	}
	
	ITEM_TYPE getType(void) {
		return this->type;
	}
	
private:
	string name;
	const ITEM_TYPE type;
};

class File : public Item {
public:
	File(string name) : Item(name, TYPE_FILE) {
		//TODO
	}
};

class Folder : public Item
{
public:
	Folder(string name) : Item(name, TYPE_FOLDER) {
		//TODO
	}

	int countSubItem(void) {
		return this->subItems.size();
	}
	
	void addSub(Item *pItem) {
		this->subItems.push_back(pItem);
	}
	
	const vector<Item *> getSubItems(void) {
		return this->subItems;
	}
private:
	vector <Item *> subItems;
};

int CountItem(string name, Item *root) {
	if(root->getType() == TYPE_FILE) {
		if(root->getName() == name) {
			return 1;
		}
		return 0;
	}
	int count = 0;
	for(const auto &item : ((Folder *)root)->getSubItems()) {
		count += CountItem(name, item);
	}
	return count;
}

int main()
{
	File f1("abc.txt"), f2("abc.txt"), f3("haha.exe"), f4("def.txt");
	Folder folder1("Folder1"), folder2("Folder2");

	folder1.addSub(&folder2);
	folder1.addSub(&f1);
	folder1.addSub(&f4);

	folder2.addSub(&f2);
	folder2.addSub(&f3);

	cout << "Folder " << folder1.getName() << " co " << 
		CountItem("abc.txt", &folder1) << " tep abc.txt" << endl;

	return 0;
}


2 Likes

cảm ơn sư huynh nhiều ạ :smiley:

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?