首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >责任链设计

责任链设计
EN

Code Review用户
提问于 2021-05-11 19:20:28
回答 1查看 73关注 0票数 2

我在设计一个责任链模式。

当处理程序只对请求执行一个操作时,它与传统的方法略有不同,即f.e。处理考虑状态代码的http响应。

但我的操纵者必须做两件事。下面是一个(虚拟的)示例,其中处理程序首先询问一个问题,然后将用户响应写到某个商店:

代码语言:javascript
复制
# some object where we keep surname and name 
class Request:
    pass


# some outer storage
store = {}


# chain of responsibility implementation

class PersonIdentifier:

    def __init__(self) -> None:
        self.handlers = []

    def add_handler(self, handler):
        if self.handlers:
            self.handlers[-1].set_next_handler(handler)
        self.handlers.append(handler)

    def handle(self, request):
        return self.handlers[0].handle_request(request)


# handlers for chain of responsibility

class BaseHandler:
    handler_name = None

    def __init__(self) -> None:
        self.next_handler = None

    def set_next_handler(self, handler):
        self.next_handler = handler


class SurnameHandler(BaseHandler):
    handler_name = 'surname'
    handler_name_answer = 'surname-answer'
    question = 'Type your surname: '

    def handle_request(self, request):
        if request.handler_name == self.handler_name:
            return self.question
        elif request.handler_name == self.handler_name_answer:
            global store
            store['surname'] = request.surname
            del request.surname
            request.handler_name = 'name'
            return self.next_handler.handle_request(request)
        else:
            return self.next_handler.handle_request(request)


class NameHandler(BaseHandler):
    handler_name = 'name'
    handler_name_answer = 'name-answer'
    question = 'Type your name: '

    def handle_request(self, request):
        if request.handler_name == self.handler_name:
            return self.question
        elif request.handler_name == self.handler_name_answer:
            global store
            store['name'] = request.name


user_request = Request()

chain = PersonIdentifier()
chain.add_handler(SurnameHandler())
chain.add_handler(NameHandler())

# first ask for surname
user_request.handler_name = 'surname'
surname = input(chain.handle(user_request))
user_request.handler_name = 'surname-answer'
user_request.surname = surname

# then ask for name
name = input(chain.handle(user_request))
user_request.name = name
user_request.handler_name = 'name-answer'
chain.handle(user_request)

print(store)

对我来说很难看。我更不喜欢的是使用handler_name和handler_name_answer。

也许你能提供更好的方法来解决我的任务?

EN

回答 1

Code Review用户

发布于 2021-05-11 21:10:28

责任链模式(特此“公司”)包括两件事:迭代和处理。

至少在Python和Java等现代编程语言中,迭代部分很容易“提取”到外部迭代。因此,最终代码看起来可能是:

代码语言:javascript
复制
result = None
for handler in handlers:
  temp_result = handler.handle(request)
  if temp_result is not None:
    result = temp_result
    break
if result is not None:
  # handled!

我认为这种方法比维护内部链更简单,而且也有同样的影响。

在CORP中,一旦找到了一个处理程序,并且它可以处理输入,就不应该执行其他处理程序。它非常类似于过滤。

但是,我认为我们在您的问题中的代码试图执行尽可能多的处理程序(因为它试图丰富更广泛的上下文)。所以也许这里并不需要公司。

也许您可以拥有丰富类,这些类有一个接受请求和上下文的方法enrich,这样每个充实类都可以更改上下文对象的状态,或者保持原样:

代码语言:javascript
复制
class BaseEnricher:
  def enrich(request, store):
    pass
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/260624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档