我有一个相当复杂的用例,需要在代码的各个部分有条件地执行相同的SQL任务。我想复制尽可能少的代码,所以我构建了一些静态帮助器方法,允许我在需要时添加一些JOIN语句。
我知道这可能已经用扩展程序做得更干净了,但是现在我的代码看起来像这样:
static class Foo
{
// Actually adds some filters which need additional JOINs
public static IQueryOver<Transaction, Transaction> FromRetailer(Retailer retailer, IQueryOver<Transaction, Transaction> baseQuery = null)
{
RetailLocation retailLocation = null;
return ForRetailerBase(baseQuery)
.Where(t => retailLocation.Retailer == retailer);
}
// Auxiliary method which only adds some JOINs needed in various places
public static IQueryOver<Transaction, Transaction> ForRetailerBase(IQueryOver<Transaction, Transaction> baseQuery = null)
{
if (baseQuery == null)
baseQuery = QueryOver(); // Custom method that creates a vanilla IQueryOver instance
// Add all sorts of JOINs needed to query the retailer
return baseQuery
.JoinAlias(...)
.Left.JoinAlias(...)
// and so on
;
}
}
在商业逻辑中,我要么实际需要按零售商进行过滤(在这种情况下,我会调用FromRetailer()
,我会调用ForRetailerBase()
),或者我不需要过滤零售商 - 但我仍然需要ForRetailerBase()
之后添加的JOIN进行分组。无条件调用ForRetailerBase()
显然会在调用FromRetailer()
时破坏事物。
我目前正以非常笨拙的方式解决这个问题,通过在业务逻辑中使用布尔值来有条件地执行ForRetailerBase()
,只有在FromRetailer()
未执行时才会执行。
我意识到这可以在两个级别上修复:要么完全使用更合适的模式,要么通过查询ForRetailerBase()
对象来有条件地在baseQuery
中添加这些JOIN,以确定它是否已经具有必要性连接。我宁愿选择第一种方法,如果有一种方法(这部分代码仍然相对年轻,我可以轻松地重构它) - 但我也会选择第二种方法。问题是,我不知道如何向任何一个方向前进。
我也意识到,表面上的解决方案是从方法ForRetailerBase()
中移除对FromRetailer()
的调用,并从业务逻辑中无条件地调用它,但这与我当前的解决方案一样糟糕,因为它需要我的业务逻辑来了解这些方法如何在内部工作。
答案 0 :(得分:1)
MenuItem nextItem = myMenu.findItem(R.id.loginim);
View nextItemView = findViewById(nextItem.getItemId());
nextItemView.setVisibility(View.VISIBLE);
,ForRetailerBase
看起来像是业务逻辑根本不应该知道的东西。它看起来像查询助手,应该由查询存储库处理。
此类存储库将公开业务的查询方法,这些方法将根据需要在内部调用FromRetailer
或ForRetailerBase
。
这样,您的企业就不需要了解如何构建查询,并且您的查询逻辑仍将在存储库中进行分解。
旁注:您的问题并不真正与您使用的特定技术相关。它在我看来更像是一个代码设计问题。也许你应该在https://softwareengineering.stackexchange.com/上提出这个问题,这是针对这些问题的(见on topic page)。