标签: visitor

策略,访问者和模板方法之间的区别是什么?

我正在上课,我们刚刚了解了这些设计模式.但是我看不出它们之间有什么区别.它们听起来像是一样的,在抽象的类上创建具体的类.有人可以帮我解决这个疑问吗?谢谢 (:

design-patterns strategy-pattern visitor template-method-pattern

15
推荐指数
1
解决办法
4324
查看次数

使用LINQ ExpressionVisitor将基本参数替换为lambda表达式中的属性引用

我正在为我们系统的一部分编写数据层,该数据层记录有关每天运行的自动作业的信息 - 作业名称,运行时间,结果,等等.

我正在使用Entity Framework与数据库交谈,但我试图将这些细节隐藏在更高级别的模块之外,我不希望实体对象本身被暴露.

但是,我想使我的界面在用于查找作业信息的标准中非常灵活.例如,用户界面应允许用户执行复杂的查询,例如"给我所有名为'hello'的作业,该作业在上午10:00到11:00之间运行失败." 显然,这看起来像是动态构建Expression树的工作.

所以我希望我的数据层(存储库)能够接受类型Expression<Func<string, DateTime, ResultCode, long, bool>>(lambda表达式)的LINQ表达式,然后在后台将该lambda转换为我的实体框架ObjectContext可以用作Where()子句中的过滤器的表达式.

简而言之,我正在尝试将类型的lambda表达式转换Expression<Func<string, DateTime, ResultCode, long, bool>>Expression<Func<svc_JobAudit, bool>>,其中svc_JobAuditEntity Framework数据对象对应于存储作业信息的表.(第一个委托中的四个参数分别对应于作业名称,运行时间,结果以及分别在MS中花费的时间)

我在使用该ExpressionVisitor课程时取得了很好的进展,直到我碰到了一堵砖墙并收到了一条InvalidOperationException错误消息:

从"VisitLambda"调用时,重写"System.Linq.Expressions.ParameterExpression"类型的节点必须返回相同类型的非null值.或者,覆盖"VisitLambda"并将其更改为不访问此类型的子项.

我完全不知所措.为什么它不允许我将引用参数的表达式节点转换为引用属性的节点?还有另一种方法可以解决这个问题吗?

以下是一些示例代码:

namespace ExpressionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Expression<Func<string, DateTime, ResultCode, long, bool>> expression = (myString, myDateTime, myResultCode, myTimeSpan) => myResultCode == ResultCode.Failed && myString == "hello";
            var result = ConvertExpression(expression);
        }

        private static Expression<Func<svc_JobAudit, bool>> …
Run Code Online (Sandbox Code Playgroud)

c# linq lambda expression visitor

13
推荐指数
2
解决办法
1万
查看次数

使用访客模式从平面DTO构建对象图

我写了一个很好的简单的小域模型,其对象图如下所示:

-- Customer
    -- Name : Name
    -- Account : CustomerAccount
    -- HomeAddress : PostalAddress
    -- InvoiceAddress : PostalAddress
    -- HomePhoneNumber : TelephoneNumber
    -- WorkPhoneNumber : TelephoneNumber
    -- MobilePhoneNumber : TelephoneNumber
    -- EmailAddress : EmailAddress
Run Code Online (Sandbox Code Playgroud)

这个结构与我必须使用的遗留数据库完全不一致,所以我定义了一个平面DTO,其中包含客户图中每个元素的数据 - 我在数据库中有视图和存储过程,这些允许我在这两个方向上使用这种扁平结构与数据进行交互,这一切都很好,花花公子:)

将域模型展平为DTO以进行插入/更新是直截了当的,但我遇到的问题是使用DTO并从中创建域模型...我的第一个想法是实现访问每个元素的访问者客户图,并根据需要从DTO注入值,有点像这样:

class CustomerVisitor
{
    public CustomerVisitor(CustomerDTO data) {...}

    private CustomerDTO Data;

    public void VisitCustomer(Customer customer)
    {
        customer.SomeValue = this.Data.SomeValue;
    }

    public void VisitName(Name name)
    {
        name.Title     = this.Data.NameTitle;
        name.FirstName = this.Data.NameFirstName;
        name.LastName  = this.Data.NameLastName;
    }

    // ... and so on …
Run Code Online (Sandbox Code Playgroud)

c# visitor dto domain-model factory-pattern

12
推荐指数
2
解决办法
2596
查看次数

Objective-C中的访客模式

我一直在寻找在Objective-C中实现Visitor设计模式的最佳方法.由于该语言不支持方法重载,因此在Java中可能发现的"传统"实现似乎是不可能的.

在我当前的实现中,我有一个Visitor协议,一个Visitor类,以及该Visitor类的几个子类,以及要访问的各种对象.一旦访问对象接受访问者,他们就会调用访问者的访问方法,将自己作为参数传递.visit方法接受一个id,然后键入它并调用它

[self performTasksOnObjectClass: (ObjectClass *)object];
Run Code Online (Sandbox Code Playgroud)

作为if/elseif/else块的一部分.这些调用由相关的Visitor子类拾取,访问者执行对象所需的任何任务.

有没有比这更好的实现访客模式的方法?我不喜欢在if/elseif/else块中使用'isKindOfClass'或'isMemberOfClass'调用.它看起来很笨重而且不够优雅.另外,以这种方式实现Visitor方法还值得吗?访问过的对象仍然可以不知道访问者,但还有其他方法可以实现这一点.

已经有人提出,委托或类集群可能是访客模式的更合适的替代方案.我有兴趣看看你们都在想什么!

编辑:我实际上在子类中调用了不同的命名方法,我已经更清楚了.

design-patterns objective-c visitor ios

12
推荐指数
1
解决办法
3421
查看次数

python中的访客模式

这是C++中访问者模式的简化实现.我有可能在Python中实现这样的东西吗?

我需要它,因为我会将对象从C++代码传递给Python中的函数.我的想法是在Python中实现一个访问者来找出Object的类型.

我的C++代码:

#include <iostream>
#include <string>


class t_element_base
{
public:
    virtual void accept( class t_visitor &v ) = 0;
};


class t_element_deriv_one: public t_element_base
{
public:
    void accept( t_visitor &v );

    std::string t_element_deriv_one_text()
    {
        return "t_element_deriv_one";
    }
};


class t_element_deriv_two: public t_element_base
{
public:
    void accept( t_visitor &v );

    std::string t_element_deriv_two_text()
    {
        return "t_element_deriv_one";
    }
};


class t_visitor
{
public:
    void visit( t_element_deriv_one& e ){ std::cout << e.t_element_deriv_one_text() << std::endl; }
    void visit( t_element_deriv_two& e ){ std::cout << e.t_element_deriv_two_text() …
Run Code Online (Sandbox Code Playgroud)

python visitor

12
推荐指数
4
解决办法
9049
查看次数

访客模式如何避免向下转型

任何人都可以在之前和之后显示示例代码,以避免向访问者模式代码进行下载

谢谢.

c++ visitor

11
推荐指数
1
解决办法
3777
查看次数

C++中是否可以使用无状态访问者模式?

我试图将以下Haskell代码转换为C++:

data List t = Nil | Cons t (List t)
Run Code Online (Sandbox Code Playgroud)

将代数数据类型直接转换为无状态访问者模式会产生以下Java代码

interface List<T> {
  <R> R accept(ListVisitor<T,R> v);
}

interface ListVisitor<T,R> {
  R visitNil();
  R visitCons(T head, List<T> tail);
}

class Nil<T> implements List<T> {
  @Override
  public <R> R accept(ListVisitor<T,R> v) {
    return v.visitNil();
  }
}

class Cons<T> implements List<T> {
  public final T head;
  public final List<T> tail;
  public Cons(T head, List<T> tail) {
    this.head = head;
    this.tail = tail;
  }
  @Override
  public <R> R accept(ListVisitor<T,R> v) { …
Run Code Online (Sandbox Code Playgroud)

c++ templates visitor stateless

11
推荐指数
1
解决办法
1015
查看次数

在C#中使用"dynamic"来实现访问者模式

我有一个应用程序,我在一系列元素上执行操作,操作的确切性质取决于所操作元素的类型.由于封装的原因,元素不适合实现操作; 这意味着它不能是元素类型的虚方法,所以'标准'多态不起作用.我提出了一个与之相关的问题,并被告知这被称为访客模式.

我以前总是使用if/elseif基于对象类型的调度程序方法实现它,然后调用适当的实现.然而,最近,我注意到同样的事情可能是使用dynamic关键字完成,如下所示:

private void ReconcileTips()
{
    foreach (var step in _definition.Steps)
    {
        ReconcileTips((dynamic)step);
    }
}

private void ReconcileTips(IBulkDispenseDefinition bulkDispense)
{
    bulkDispense.TipType = ReconcileTip(bulkDispense.TipType);
}

private void ReconcileTips(ImportScreenDefinition importScreen)
{
    foreach (var usage in importScreen.ReagentUsages)
        usage.TipType = ReconcileTip(usage.TipType);
}

private void ReconcileTips(BuildScreenDefinition buildScreen)
{
    foreach (var function in buildScreen.Functions)
        function.TipType = ReconcileTip(function.TipType);
}
Run Code Online (Sandbox Code Playgroud)

类似的模式可以用于与类结构并行的其他操作,比如为每个元素创建视图模型_definition.Steps.我们的想法是,编译器基本上将其转换为if/elseif我之前编写的相同逻辑,从而节省了我的努力.那么,有几个问题:

  1. 动态调度是否有任何问题我没有考虑过?我相信这相当于执行一系列if (x is TypeA) Do((TypeA)x) else...,但我可能是错的.

  2. 这比较长的if/elseif方法更清洁,更容易理解吗?

.net c# dynamic visitor

11
推荐指数
2
解决办法
1819
查看次数

如何使用antlr4访客

我是antlr的初学者.我试图在我的代码中使用访问者并遵循网络上的说明.但是,我发现访问者没有进入我创建的方法.愿谁有人告诉我我做错了什么?

这是我的访客:

import java.util.LinkedList;
import org.antlr.v4.runtime.misc.NotNull;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Sherwood
 */
public class ExtractMicroBaseVisitor extends MicroBaseVisitor<Integer> {
    //LinkedList<IR> ll = new LinkedList<IR>();
    //MicroParser parser;
    //System.out.println("11");

    @Override 
    public Integer visitPgm_body(@NotNull MicroParser.Pgm_bodyContext ctx){
        System.out.println(ctx.getText());
        return 467;
    }

    @Override
    public Integer visitProgram(@NotNull MicroParser.ProgramContext ctx){
        System.out.println("11");
        return 456;
    }

}
Run Code Online (Sandbox Code Playgroud)

如您所见,当输入方法"visitProgram"时,stdout应打印11.但输出屏幕没有给我任何东西(null类型).

这是我的主要代码:

import java.io.IOException;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
/**
 *
 * @author Sherwood
 */ …
Run Code Online (Sandbox Code Playgroud)

java parsing visitor antlr4

11
推荐指数
1
解决办法
1万
查看次数

Java:使用RuntimeException从访问者中逃脱

我很有诱惑力使用未经检查的异常作为Java程序中的短路控制流构造.我希望有人能以更好,更清洁的方式告诉我这个问题.

我的想法是,我希望减少访问者对子树的递归探索,而不必在每个方法调用中检查"停止"标志.具体来说,我正在使用抽象语法树上的访问者构建控制流图.returnAST中的语句应该停止对子树的探索,并将访问者发送回最近的封闭if/then或循环块.

Visitor超类(从XTC库)定义

Object dispatch(Node n)
Run Code Online (Sandbox Code Playgroud)

通过表单的反射方法回调

Object visitNodeSubtype(Node n)
Run Code Online (Sandbox Code Playgroud)

dispatch 没有声明抛出任何异常,所以我声明了一个扩展的私有类 RuntimeException

private static class ReturnException extends RuntimeException {
}
Run Code Online (Sandbox Code Playgroud)

现在,return语句的visitor方法看起来像

Object visitReturnStatement(Node n) {
    // handle return value assignment...
    // add flow edge to exit node...
    throw new ReturnException();
}
Run Code Online (Sandbox Code Playgroud)

并且每个复合语句都需要处理 ReturnException

Object visitIfElseStatement(Node n) {
  Node test = n.getChild(0);
  Node ifPart = n.getChild(1);
  Node elsePart = n.getChild(2);

  // add flow edges to if/else... 

  try{ dispatch(ifPart); } catch( ReturnException e ) { …
Run Code Online (Sandbox Code Playgroud)

java callcc exception visitor

10
推荐指数
1
解决办法
2903
查看次数