• 全部
  • 问答

GoF中command模式的参数和返回值的问题有好的解决方法吗

maomaostevencao 2004-05-08 02:30:21
GoF中的command模式中,仅仅详细叙述了非转发式实现方式。对于返回值和可变参数的问题都没有提到。loki的实现方法在visual studio 6.0又不被支持,各位有什么好的解决方法吗?
...全文
103 点赞 收藏 11
写回复
11 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
stonespace 2004-05-09
参数和返回值为什么不能作为command子类的数据成员?比如鼠标事件中鼠标单击时把单击位置写入command子类的数据成员中,然后Execute就不需要参数了。

难道响应鼠标事件的代码不知道command子类类型?command实例是原型或者工厂创建的?没有必要。

如果一定要这样,可以做一个抽象的参数基类和返回值基类,对不同的command子类相应定义具体的参数类。
回复
Fusuli 2004-05-09
在C#里你可以这样,在接口中将Execute()方法的参数和返回值都声明为object,在具体实现类里进行转换:
interface Command{
object Exectue(object parameter);
}

class SomeClass:Command{
public object Execute(object parameter){
int realparameter = (int)parameter;
int returnvalue;
/*...........*/

return returnvalue;
}

}
回复
maomaostevencao 2004-05-09
dearmite(笨笨的我*_^) :
你贴的是GoF中的例子,但是仍然没有解决可变参数和返回值的问题啊?
对于转发式command:
各个command子类执行时需要的参数的类型和个数是不固定的,GoF中使用的是非转发式,而且不知是故意还是无意,GoF举的例子都是没有参数的。这种方法对于响应例如鼠标单击事件是无能为力的,因为鼠标事件中鼠标单击时还有诸如单击位置等这些参数。还有就是各个command子类的返回值可能也是不一样的,GoF中也没有提到。

Loki中的关键就是使用TypeList,但是不知道的vc6移植版本有没有移植成功,我正在看。
回复
Chuanyan 2004-05-09
哇,好详细~~
回复
w_rose 2004-05-09
当然,软工应该具有实用性,不应该仅仅针对某些编程语言。
回复
w_rose 2004-05-09
软件分析和设计难道不是软工?

如果搞软工的就是搞“管人”的空洞的那一套,那么这样的人在公司里越少越好。
回复
dearmite 2004-05-09
这回VC6 绝对认,
:)
回复
dearmite 2004-05-09
/*
*/
#include "Foundation.H"

class Document {
public:
Document(const char*);
void Open();
void Paste();
};

class Application {
public:
Application();
void Add(Document*);
};
/*
*/
class Command {
public:
virtual ~Command();

virtual void Execute() = 0;
protected:
Command();
};
/*
*/
class OpenCommand : public Command {
public:
OpenCommand(Application*);

virtual void Execute();
protected:
virtual const char* AskUser();
private:
Application* _application;
char* _response;
};
/*
*/
OpenCommand::OpenCommand (Application* a) {
_application = a;
}
/*
*/
void OpenCommand::Execute () {
const char* name = AskUser();

if (name != 0) {
Document* document = new Document(name);
_application->Add(document);
document->Open();
}
}
/*
*/
class PasteCommand : public Command {
public:
PasteCommand(Document*);

virtual void Execute();
private:
Document* _document;
};
/*
*/
PasteCommand::PasteCommand (Document* doc) {
_document = doc;
}

void PasteCommand::Execute () {
_document->Paste();
}
/*
*/
template <class Receiver>
class SimpleCommand : public Command {
public:
typedef void (Receiver::* Action)();

SimpleCommand(Receiver* r, Action a) :
_receiver(r), _action(a) { }

virtual void Execute();
private:
Action _action;
Receiver* _receiver;
};
/*
*/
template <class Receiver>
void SimpleCommand<Receiver>::Execute () {
(_receiver->*_action)();
}
/*
*/
class MyClass {
public:
void Action();
};
void dummy () {
/*
*/
MyClass* receiver = new MyClass;
// ...
Command* aCommand =
new SimpleCommand<MyClass>(receiver, &MyClass::Action);
// ...
aCommand->Execute();
/*
*/
}
/*
*/
class MacroCommand : public Command {
public:
MacroCommand();
virtual ~MacroCommand();

virtual void Add(Command*);
virtual void Remove(Command*);

virtual void Execute();
private:
List<Command*>* _cmds;
};
/*
*/
void MacroCommand::Execute () {
ListIterator<Command*> i(_cmds);

for (i.First(); !i.IsDone(); i.Next()) {
Command* c = i.CurrentItem();
c->Execute();
}
}
/*
*/
void MacroCommand::Add (Command* c) {
_cmds->Append(c);
}

void MacroCommand::Remove (Command* c) {
_cmds->Remove(c);
}
/*
*/

回复
dearmite 2004-05-09
/*
*/
#ifndef Foundation_H
#define Foundation_H
/*
*/
class ostream;
const long DEFAULT_LIST_CAPACITY = 200;
#ifndef defs_h
#define defs_h
/*
*/
typedef int bool;
const int true = 1;
const int false = 0;
/*
*/
#endif
/*
*/
template <class Item>
class List {
public:
List(long size = DEFAULT_LIST_CAPACITY);
List(List&);
~List();
List& operator=(const List&);
/*
*/
long Count() const;
Item& Get(long index) const;
Item& First() const;
Item& Last() const;
bool Includes(const Item&) const;
/*
*/
void Append(const Item&);
void Prepend(const Item&);
/*
*/
void Remove(const Item&);
void RemoveLast();
void RemoveFirst();
void RemoveAll();
/*
*/
Item& Top() const;
void Push(const Item&);
Item& Pop();
};
/*
*/
template <class Item>
class Iterator {
public:
virtual void First() = 0;
virtual void Next() = 0;
virtual bool IsDone() const = 0;
virtual Item CurrentItem() const = 0;
protected:
Iterator();
};
/*
*/
template <class Item>
class ListIterator : public Iterator<Item> {
public:
ListIterator(const List<Item>* aList);
/*
*/
virtual void First();
virtual void Next();
virtual bool IsDone() const;
virtual Item CurrentItem() const;
};
/*
*/
typedef float Coord;
/*
*/
class ostream;
class istream;
/*
*/
class Point {
public:
static const Point& Zero;
/*
*/
Point(Coord x = 0.0, Coord y = 0.0);
/*
*/
Coord X() const; void X(Coord x);
Coord Y() const; void Y(Coord y);
/*
*/
friend Point& operator+(const Point&, const Point&);
friend Point& operator-(const Point&, const Point&);
friend Point& operator*(const Point&, const Point&);
friend Point& operator/(const Point&, const Point&);
/*
*/
Point& operator+=(const Point&);
Point& operator-=(const Point&);
Point& operator*=(const Point&);
Point& operator/=(const Point&);
/*
*/
Point operator-();
/*
*/
friend bool operator==(const Point&, const Point&);
friend bool operator!=(const Point&, const Point&);
/*
*/
friend ostream& operator<<(ostream&, const Point&);
friend istream& operator>>(istream&, Point&);
};
/*
*/
class Rect {
public:
static const Rect& Zero;
/*
*/
Rect(Coord x, Coord y, Coord w, Coord h);
Rect(const Point& origin, const Point& extent);
/*
*/
Coord Width() const; void Width(Coord);
Coord Height() const; void Height(Coord);
Coord Left() const; void Left(Coord);
Coord Bottom() const; void Bottom(Coord);
/*
*/
Point& Origin() const; void Origin(const Point&);
Point& Extent() const; void Extent(const Point&);
/*
*/
void MoveTo(const Point&);
void MoveBy(const Point&);
/*
*/
bool IsEmpty() const;
bool Contains(const Point&) const;
};
/*
*/
void dummy_found () {
Rect* tmp = new
/*
*/
Rect(Point(0, 0), Point(0, 0));
/*
*/
}
#endif
/*
*/

回复
Fusuli 2004-05-08
软工版越来越像面向对象分析与设计版了
回复
stonespace 2004-05-08
返回值和参数都可以作为command对象的数据成员,定一些方法设置参数和取回返回值。


回复
发帖
研发管理
创建于2007-08-27

1200

社区成员

软件工程/管理 管理版
申请成为版主
帖子事件
创建了帖子
2004-05-08 02:30
社区公告
暂无公告