关于将算法与类分离的讨论很多.但是,有一件事没有解释.
他们像这样使用访客
abstract class Expr {
public <T> T accept(Visitor<T> visitor) {visitor.visit(this);}
}
class ExprVisitor extends Visitor{
public Integer visit(Num num) {
return num.value;
}
public Integer visit(Sum sum) {
return sum.getLeft().accept(this) + sum.getRight().accept(this);
}
public Integer visit(Prod prod) {
return prod.getLeft().accept(this) * prod.getRight().accept(this);
}
Run Code Online (Sandbox Code Playgroud)
Visitor不会直接调用visit(element),而是要求元素调用其visit方法.它与所宣称的关于访客的阶级无意识的观念相矛盾.
PS1请用您自己的话解释或指出确切的解释.因为我得到的两个回答是指一般的和不确定的.
PS2我的猜测:由于getLeft()返回基本Expression,调用visit(getLeft())将导致visit(Expression),而getLeft()调用visit(this)将导致另一个更合适的访问调用.因此,accept()执行类型转换(也称为转换).
PS3 Scala的模式匹配=类固醇上的访客模式显示没有接受方法访问者模式的简单程度.维基百科补充说:通过链接一篇论文,显示" accept()当反射可用时,方法是不必要的;为该技术引入术语'Walkabout'."
我已经学习并检查了dynamicC#4 中关键字的优点.
任何人都可以告诉我这个的缺点.指dynamicVS Var/ Object/ reflection???
哪个更重要.是dynamic在运行时更加强大?
我有这个代码:
class Event{};
class CustomEvent:public Event{};
class Handler
{
public:
virtual void inform(Event e ){}
};
class CustomHandler : public Handler
{
public:
void inform(CustomEvent e){}
};
CustomEvent cEvent;
Handler* handler = new CustomHandler;
//this calls Handler::inform(Event), not CustomHandler::(CustomEvent) , as I expected
handler->inform(cEvent);
Run Code Online (Sandbox Code Playgroud)
如果我将代码更改为:
class Handler
{
public:
virtual void inform(Event e ){}
virtual void inform(CustomEvent e){}
};
class CustomHandler : public Handler
{
public:
void inform(CustomEvent e){}
};
CustomEvent cEvent;
Handler* handler = new CustomHandler;
//this calls CustomHandler::(CustomEvent) …Run Code Online (Sandbox Code Playgroud) 我有一个数据库关系,如下所示.域对象是基于LINQ to SQL ORM创建的.
付款包括现金付款和礼品券付款.假设购买总额为550.可以按以下组件支付
1 Gift Coupon Valued 300
1 Gift Coupon Valued 200
I Cash Currency Valued 50
Run Code Online (Sandbox Code Playgroud)

我正在使用ORM的"InsertOnSubmit"功能插入新的付款记录.以下代码工作正常.但是,如果我公司使用信用卡引入新的支付组件,我需要更改我的"付款"域类.如何使支付类打开以进行扩展并关闭仍在使用ORM的更改?
注意:Payment类具有行为(例如GetTotalAmountCollected).我正在努力使"付款"类满足OCP.
注意:优惠券类型有特定的行为.优惠券发行日期是否小于2000年1月1日,它不应用于计算总金额(即,CouponValue应为零).请参阅使用策略模式重构代码.
注意:我使用的是.Net 4.0
参考:
C#代码:
public class PaymentAppService
{
public RepositoryLayer.ILijosPaymentRepository Repository { get; set; }
public void MakePayment()
{
DBML_Project.Payment paymentEntity = new DBML_Project.Payment();
paymentEntity.PaymentID = 1;
paymentEntity.PaymentType = "PurchaseP";
DBML_Project.CashPayment cashObj = new …Run Code Online (Sandbox Code Playgroud) (首先是上下文和问题,帖子底部的骨架代码)
我们正在创建和实现一个C++框架,以便在Arduino等环境中使用.
为此,我想使用Observer模式,其中任何对传感器(Observables)的状态更改感兴趣的组件都可以自己注册,并且Observable会通过调用notification()Observer 的方法将其自身作为参数来通知这些更改.
一个观察者可以观察到多个Observable,反之亦然.
问题在于Observer需要提取Observable的当前状态并对其执行某些操作,并且此当前状态可以采用所有形式和大小,具体取决于Observable的特定传感器.
它当然可以是序数值,它们是有限的并且可以被编码出来,就像我在下面的代码中使用该方法所做的那样,getValueasInt()但它也可以是传感器特定的结构,即对于RealTimeClock,它提供日期和时间的结构值.结构当然在编译时定义,并针对特定传感器进行修复.
我的问题:什么是最优雅,未来修改的解决方案或模式?
编辑:请注意,由于Arduino限制,因此无法进行dynamic_cast <>构造
我创建了以下类层次结构(框架代码):
class SenseNode
{
public:
SenseNode() {};
SenseNode(uint8_t aNodeId): id(aNodeId) {}
virtual ~SenseNode() {}
uint8_t getId() { return id; };
private:
uint8_t id = 0;
};
class SenseStateNode : virtual public SenseNode
{
public:
SenseStateNode(uint8_t aNodeId) : SenseNode(aNodeId) {}
virtual ~SenseStateNode() {}
/** Return current node state interpreted as an integer. */
virtual int getValueAsInt();
};
class SenseObservable: public SenseStateNode
{
public:
SenseObservable(uint8_t …Run Code Online (Sandbox Code Playgroud) 在网上搜索后,我找不到这个问题的答案:
我有这个重载的方法:
foo(Base* base);
foo(Derived* derived);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,"Derived"是"Base"的子类.
我打电话的时候:
foo(new Derived());
Run Code Online (Sandbox Code Playgroud)
我注意到总是调用第一个重载方法,而我想实现相反的结果(调用以"Derived*"对象作为参数的方法).
怎么解决这个?谢谢.
编辑:
好的,这是我的实际情况:
我有一个UIWidget和一个UIScoreLabel类.UIScoreLabel派生自UIWidget.我还有一个GameEvent类(Base)和一个P1ScoreGameEvent类(Derived).
UIWidget:
virtual void handleGameEvent(GameEvent* e) { printf("ui_widget"); }
Run Code Online (Sandbox Code Playgroud)
UIScoreLabel:
virtual void handleGameEvent(P1ScoreGameEvent* e) { printf("ui_score_label"); }
Run Code Online (Sandbox Code Playgroud)
这是电话:
UIWidget* scoreLabel = new UIScoreLabel();
scoreLabel.handleGameEvent(new P1ScoreGameEvent());
Run Code Online (Sandbox Code Playgroud)
输出:
ui_widget
Run Code Online (Sandbox Code Playgroud)
我不明白我做错了什么.
c++ ×3
.net ×2
c# ×2
arduino ×1
c#-4.0 ×1
dynamic ×1
inheritance ×1
linq-to-sql ×1
observable ×1
overloading ×1
overriding ×1
visitor ×1