"泄漏抽象"一词是什么意思?(请用例子解释.我经常很难完成一个理论.)
memory-leaks abstraction programming-languages functional-programming leaky-abstraction
什么是流畅的界面?我找不到一个好的定义,但我得到的只是我不熟悉的语言中的长代码示例(例如C++).
另外,什么是漏洞抽象?
谢谢
我在创建一个新的ASP.NET MVC项目时非常关注.一些教程推荐使用MVC Contrib.如果它实现了使用ASP.NET MVC提高工作效率的承诺,我想获得Stack Overflow社区的意见.基本上MVC Contrib的好处值得为我的应用程序添加另一个漏洞抽象?
在Thoughtworks技术雷达上 - 他们将Java Server Faces 搁置- 说明:
我们继续看到团队使用JSF - JavaServer Faces遇到麻烦 - 并且建议您避免使用这种技术.团队似乎选择JSF,因为它是一个J2EE标准,而没有真正评估编程模型是否适合它们.我们认为JSF存在缺陷,因为它试图抽象出HTML,CSS和HTTP,正好与现代Web框架相反.与ASP.NET webforms一样,JSF尝试在无状态协议HTTP之上创建有状态,最终导致涉及共享服务器端状态的大量问题.我们知道JSF 2.0的改进,但认为该模型从根本上被打破.我们建议团队使用简单的框架,拥抱和理解Web技术,包括HTTP,HTML和CSS.
据我所知,如果你用无状态抽象包装像http的无状态协议,他们基本上会说你可能会陷入陷阱.也就是说,一个团队可能会遇到麻烦.
我的问题是:是否有证据表明Thoughtworks断言JSF是一个破碎的抽象?
我在这里寻找指针和信息,我会做这个CW,因为我怀疑它没有一个正确答案.这是针对C#的,因此我将在下面对Linq进行一些引用.我也为这篇长篇大论道歉.让我在这里总结一下这个问题,然后是完整的问题.
简介:在UI/BLL/DAL/DB 4层应用程序中,如何更改用户界面,以显示更多列(例如在网格中),避免泄漏通过业务逻辑层进入数据访问层,掌握要显示的数据(假设它已经在数据库中).
让我们假设一个有3(4)层的分层应用程序:
在这种情况下,DAL负责构造SQL语句并对数据库执行它们,返回数据.
"正确"构建这样一个层的唯一方法就是总是"select*"吗?对我来说这是一个很大的禁忌,但让我解释为什么我在想.
让我们说,对于我的用户界面,我希望显示所有拥有活跃就业记录的员工."活跃"是指今天的就业记录包含今天(或者甚至是我可以在用户界面中设定的日期).
在这种情况下,假设我想向所有这些人发送一封电子邮件,因此我在BLL中有一些代码可以确保我还没有向同一个人发送过电子邮件,等等.
对于BLL,它需要最少量的数据.也许它调用数据访问层来获取活动员工列表,然后调用以获取它发送的电子邮件列表.然后它加入这些并构造一个新列表.也许这可以在数据访问层的帮助下完成,这并不重要.
重要的是,对于业务层,它实际上并不需要太多数据.也许它只需要每个员工的唯一标识符,对于两个列表,匹配,然后说"这些是活动的那些的唯一标识符,您还没有发送电子邮件到".然后构建DAL代码,构造只检索业务层需要的SQL语句吗?IE浏览器.只是"SELECT id FROM employees WHERE ..."?
那么我该怎么做用户界面呢?对于用户来说,这或许会是最好的,包括了很多信息,这取决于为什么我要发送电子邮件.例如,我可能想要包括一些基本的联系信息,或者他们工作的部门,或者他们的经理姓名等,而不是说我至少要显示姓名和电子邮件地址信息.
用户界面如何获取数据?我是否更改了DAL以确保将足够的数据返回给UI?我是否更改BLL以确保它为UI返回足够的数据?如果从DAL返回到BLL的对象或数据结构也可以发送到UI,那么BLL可能不需要进行太多的更改,但是UI的要求会影响超出应该与之通信的层. .如果这两个世界在不同的数据结构上运行,则可能必须对两者进行更改.
那么当UI被更改时,为了进一步帮助用户,通过添加更多列,我需要多深才能更改UI?(假设数据已存在于数据库中,因此不需要进行任何更改.)
提出的一个建议是使用Linq-To-SQL和IQueryable,这样如果DAL处理什么(如在什么类型的数据中)和为什么(如WHERE-clauses中)返回IQueryables,那么BLL可以可能会将这些内容返回到UI,然后可以构建一个Linq查询来检索所需的数据.然后,用户界面代码可以拉入所需的列.这将有效,因为使用IQuerables,UI最终会实际执行查询,然后它可以使用"select new {X,Y,Z}"来指定它需要的内容,甚至可以在必要时加入其他表.
这看起来很混乱.UI执行SQL代码本身,即使它已隐藏在Linq前端后面.
但是,为了实现这一点,不应该允许BLL或DAL关闭数据库连接,并且在IoC类型的世界中,DAL服务可能比UI代码所希望的更快地被处理掉,因此Linq查询可能最终会出现"无法访问已处置对象"的异常.
所以我正在寻找指针.我们有多远?你是怎么处理的?我认为UI的更改将通过BLL泄漏到DAL中是一个非常糟糕的解决方案,但是现在它看起来并不像我们能做得更好.
请告诉我我们有多愚蠢并证明我错了?
请注意,这是一个遗留系统.多年来,更改数据库模式的范围还不在范围内,因此使用ORM对象的解决方案基本上与"select*"相当,实际上并不是一种选择.我们有一些大型表格,我们希望避免在整个图层列表中提取.
c# business-logic data-access-layer isolation leaky-abstraction
我正在一些图形API(DirectX9和DirectX11)上面写一个抽象层,我想你的意见.
传统上,我会为每个想要抽象的概念创建一个基类.
因此,在典型的OO方式中,我将有一个类Shader和2个子类DX9Shader和DX11Shader.
我会重复纹理等过程...当我需要实例化它们时,我有一个抽象工厂,它将根据当前的图形API返回适当的子类.
在RAII之后,返回的指针将封装在std :: shared_ptr中.
到目前为止一直很好,但就我而言,这种方法存在一些问题:
这促使我重新设计我的工作方式:我认为我可以返回资源的原始指针,并让图形API自行清理,但仍然存在客户端悬挂指针和接口问题的问题.我甚至认为手动引用计数像COM,但我认为这将是一个倒退(纠正我,如果我错了,来自shared_ptr世界,手动引用计数似乎是原始的).
然后我看到了Humus的工作,其中所有的图形类都由整数ID表示(很像OpenGL的作用).创建一个新对象只返回其整数ID,并在内部存储指针; 它完全不透明!
代表抽象的类(例如DX9Shader等......)都隐藏在设备API后面,这是唯一的接口.
如果想要设置纹理,只需调用device-> SetTexture(ID),其余的就在幕后发生.
失败的原因是API的隐藏部分膨胀,需要很多锅炉板代码才能使其工作,我不是一个全能类的粉丝.
任何想法/想法?
我正在实现一个存储库模式.我的主要原因是:
通用存储库与否?
我遇到的问题是我是否应该有一个通用的存储库.一种IQueryable<T> Query()
方法将为调用代码提供构造特定查询的手段.这里的问题是这是漏洞抽象 - 实体框架细节现在泄漏到我的客户端代码中.
这种影响单元测试怎么样? 我还能ICustomerRepository
用这个实现模拟吗?
这种效果如何影响我的持久层?像Azure存储表或NHibernate.
否则我将不得不实现非常具体的查询方法ICustomerRepository
,例如GetIsActiveByFirstName()
和GetIsActiveByDistrict()
.我不喜欢这个,因为我的存储库类将变得拥挤不同的查询方法.该系统有数百种型号,因此可以有数百甚至数千种这样的方法来编写和维护.
entity-framework leaky-abstraction repository-pattern onion-architecture entity-framework-5
我正在实现一个ITracker
看起来像这样的接口:
public interface ITracker
{
void Track(ITrackerEvent trackerEvent);
}
Run Code Online (Sandbox Code Playgroud)
我最初创建了这个包装Mixpanel.NET的接口的实现.然后我创建了另一个包装Application Insights的程序.但是,Application Insights需要Flush()
将数据发送到服务器.
我不想仅仅因为其中一个实现需要一个方法而污染ITracker
接口Flush()
.它会感觉像是一个漏洞的抽象.
但是,我需要在某个时候调用此方法(可能在应用程序关闭时)并且不希望每次Track
调用时都这样做.
当Tracker在会话结束时被垃圾收集时,是否可以调用方法?这甚至是一个好方法吗?
我觉得我在这里错过了一招!
以下代码片段提供了非常奇怪的输出.我期待溢出(Python给出一个MemoryError)
#include <iostream>
#include <vector>
int main()
{
std::vector<int> a{1,2,3};
for( auto const & item : a)
a.push_back(item);
for( auto const & item : a)
std::cout<<item<<',';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
产量:1,2,3,1,0,3,
我该如何解释这个结果?
如果你在Python中做类似的事情,它会给出内存错误.
>>> a = range(0,20)
>>> for i in a:
a.append(i)
Traceback (most recent call last):
File "<pyshell#3>", line 2, in <module>
a.append(i)
MemoryError
>>>
Run Code Online (Sandbox Code Playgroud)
我想到了这个问题,因为上面编写代码的方式被认为是绑定安全的.并且对于绑定的安全容器不应该在生长/收缩期间foreach type iteration
.所以,这是一个漏洞的抽象.
有没有办法可以包装这个foreach
循环,以便在循环体中不允许任何导致大小修改/重新分配的操作.
如何在没有过滤和没有聚合(sum()
等等)的非空序列上产生迭代器,什么都不产生?
考虑一个简单的例子:
sequence = ['a', 'b', 'c']
list((el, ord(el)) for el in sequence)
Run Code Online (Sandbox Code Playgroud)
这[('a', 97), ('b', 98), ('c', 99)]
按预期产生.
现在,只需将ord(el)
out 换成一个表达式,该表达式使用某个生成器的第一个值(...).next()
- 原谅人为的例子:
def odd_integers_up_to_length(str):
return (x for x in xrange(len(str)) if x%2==1)
list((el, odd_integers_up_to_length(el).next()) for el in sequence)
Run Code Online (Sandbox Code Playgroud)
这产生了[]
.是的,空单.没有('a',
东西)
元组.没有.
但我们不是过滤,聚合或减少.n
没有过滤或聚合的对象上的生成器表达式必须产生n
对象,对吗?这是怎么回事?
abstraction ×3
c# ×2
c++ ×2
oop ×2
python ×2
.net ×1
asp.net ×1
asp.net-mvc ×1
directx ×1
generator ×1
isolation ×1
iterator ×1
jsf ×1
jsf-2 ×1
memory-leaks ×1
mvccontrib ×1
vector ×1