与基于角色和权限呈现组件相关的设计模式或架构?
Posted
技术标签:
【中文标题】与基于角色和权限呈现组件相关的设计模式或架构?【英文标题】:A design pattern or architecture related to rendering components based on roles and permissions? 【发布时间】:2022-01-19 01:17:19 【问题描述】:我想知道是否有软件设计模式可以解决我面临的挑战。我有一个 Web 应用程序,它适用于几种不同的用户角色类型,如 SuperAdmin
、Admin
、Reseller
、Dealer
、Customer
、Volunteer
等...
我们的 React 代码中充斥着 if 语句,它们检查一个人的角色以及其他条件来决定“什么类型的 ui 组件”来呈现它们。这是一个非常简化的示例:
// Container.js
<div>
<h1>Something</h1>
['SuperAdmin', 'Admin'].includes(user.role) && (<input type="text" value="record.first_name" />)
['Reseller', 'Dealer'].includes(user.role) && (<span className="border-2">record.first_name</span>)
['Customer', 'Volunteer'].includes(user.role) && process.env.NETWORK_MODE === 'intranet' && (
<div className="bg-grey">
<span>Created at record.create_at</span>
<span>This customer wants to be anonymous</span>
</div>
)
['Reseller'].includes(user.role) && user.accountBalance > 0 && user.statementDate > (new Date()) && (
<div>Please pay your bills</div>
)
</div>
上面的例子对我们来说很难管理,因为有超过 100 个组件。当我们需要更改角色类型的访问权限或添加其他条件时,我们必须遍历每个组件并查找任何杂散的 if 语句。我们正在考虑编写一些自动化测试,但感觉我们需要重构 UI 代码才能实现。
是否有一些与我的情况相关的软件工程设计模式?如果是这样,请说出名称,我会仔细阅读。
现在,我正在考虑这样的方法:
// Container.js
<div>
<h1>Something</h1>
<Customer user=user />
<BillNotice user=user />
</div>
// Customer.js
const Customer = (user) =>
if(['Admin', 'SuperAdmin'].includes(user.role)) return <CustomerVersion1 />;
if(['Role', 'Role'].includes(user.role) && condition1 && condition2 ...etc...) return <CustomerVersion2 />;
if(['Role', 'Role'].includes(user.role) && condition1 && condition2 ...etc...) return <CustomerVersion3 />;
...etc...
const CustomerVersion1 = () => <Component />;
const CustomerVersion2 = () => <Component />;
const CustomerVersion3 = () => <Component />;
...etc...
// BillNotice.js
const BillNotice = (user) =>
if(['Admin', 'SuperAdmin'].includes(user.role)) return <BillNotice1 />;
if(['Role', 'Role'].includes(user.role) && condition1 && condition2 ...etc...) return <BillNotice2 />;
if(['Role', 'Role'].includes(user.role) && condition1 && condition2 ...etc...) return <BillNotice3 />;
...etc...
const BillNotice1 = () => <Component />;
const BillNotice2 = () => <Component />;
const BillNotice3 = () => <Component />;
基本上,我让每个组件负责决定它应该如何呈现自己。然后我可以通过模拟用户参数为每个组件编写单元测试,并查看是否返回了适当的组件。如果这种方法真的有名字,那就太好了,我可以阅读更多内容!
【问题讨论】:
【参考方案1】:就我的经验而言,没有灵丹妙药来应对这么多条件,毕竟它存在,我们需要在某个地方实现它们, 但是,如果 IMO 设计良好,我们只能编写一次(在一个地方管理)。
对于这种情况,也许使用 hook 是一种很好的做法。
./钩子// control the logic in one place
const useAuthControl = (userRole, conditions) =>
// return as demand, maybe a more nested structure in the real world case
return
isAdmin: ['Admin', 'SuperAdmin'].includes(userRole),
isRole: ['Role', 'Role'].includes(userRole) && condition1 && condition2 ...etc...,
isAnotherRole: ['Role', 'Role'].includes(userRole) && condition1 && condition2 ...etc...,
./组件
// pass the condition dependencies if necessary
const isAdmin, isRole, isAnotherRole, ... = useAuthControl(userRole, ...condition);
// use for different components with a simpler method to write everywhere
return (
<>
isAdmin && ...
isRole && ...
isAnotehrRole && ...
</>
)
// other components as well
return (
<>
isAdmin && ...
isRole && ...
isAnotehrRole && ...
</>
)
【讨论】:
以上是关于与基于角色和权限呈现组件相关的设计模式或架构?的主要内容,如果未能解决你的问题,请参考以下文章