业务逻辑类中的抽象
当您从库中调用方法时,您希望它完全按照其名称所暗示的那样执行操作。
Connection c = driver.getConnection();
- 返回连接
- 如果失败则报告错误
- 不做超出预期的事情
当编写“库代码”时,很容易坚持解耦,内聚、抽象原则。大多数时候,不遵守这些规定意味着设计上的错误。
但是当你在业务逻辑中时,就会出现一些困难,也许必须改变视角。在业务逻辑级别我说:
session.connect(); //session is of Session type, my "business logic class"
我希望它读取配置文件,如果找不到它,则采用默认值,连接,做一些检查,决定需要向用户通知哪个警告,例如数据库版本比客户端软件旧。
如果你说一个方法不应该做所有这些事情,因为它必须具有内聚性,并且严格应用这一点,那么你最终会得到一个只有一行的 connect 方法:
public class Session {
...
Connection c;
public void connect() {
c = driver.getConnection();
}
}
即方法 connect业务类Session的
会折叠到底层类。
剩下的任务呢?读取文件,检查数据库版本等?
您将业务代码推迟到将执行所有逻辑的“大方法”。
这正是我的观点。
如果您在业务逻辑上下文中应用内聚和解耦原则,您将无法将任务细分为更小的子任务,您将有一些大的“整体”方法来完成所有工作并且可读性很差。
我发现低级库 (Driver.getConnection()) 的良好原则(内聚、抽象)对于业务逻辑来说相当不够。
我的想法是:
- 内聚力必须用一个全新的概念取代
- 内聚力必须“拉伸”到一定程度
由于我更喜欢第二个,我的问题是那是什么观点。
When you call a method from a library you expect that it does exactly what its name implies it will do.
Connection c = driver.getConnection();
- to give back a connection
- to report an error if it fails
- not to do more than expected
When writing "library code" it is very easy to stick with the decoupling, cohesion, abstraction principles. Not adhering to these, most times, means an error in design.
But when you are in business logic, some difficulties arise and perhaps the perspective has to be changed. At the business logic level i say:
session.connect(); //session is of Session type, my "business logic class"
and i expect that it reads the config file, takes defaults if it doesn't find it, connect, do some checking, decide which warning need to be notified to the user, for example the fact that the database version is older than the client software.
If you say that a method shouldn't do all this stuff because it must be cohesive, and apply this rigorously, you'll end up with a connect method with just one line:
public class Session {
...
Connection c;
public void connect() {
c = driver.getConnection();
}
}
that is, the method connect
of the business class Session will collapse to the underlying classes.
And the rest of the tasks? Read the file, check the db version etc?
You are postponing the businness code to a "big method" that will do all the logic.
And this is exactly my point.
If you apply cohesion and decoupling principles in a business logic context, you'll fail to subdivide tasks into smaller sub-tasks, and you will have some big "monolithic" methods doing all the work and being poorly readable.
I find the good principles (cohesion, abstraction) for low level libraries (Driver.getConnection()) quite inadequate for businness logic.
My ideas are:
- cohesion has to be replaced with an entirely new concept
- cohesion has to be "stretched" to a certain point
And since i prefer the 2nd, my question is what is that point.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您缺少 OOP 概念和良好设计中的一些部分。如果你的代码不再可读 - 正如 Martin Fowler 提到的那样,如果你的代码有异味 - 因为你试图增加内聚性或减少耦合(你无法消除与 %0 的耦合,或者无法将内聚性提高到 100%。当您尝试此操作时,您会得到类似于上面的 connect() 示例的代码),您走错了路。因为,这些概念是为了让你的代码更具可读性。还有诸如“提取方法”之类的重构概念来增加内聚性。内聚和耦合通常与形容词一起使用,“低耦合”和“高内聚”。它们必须有多低或多高,设计师必须决定/优化它。顺便说一句,如果您调用 session.connect() ,我不认为必须配置连接。为此,还有许多其他概念,如连接工厂、会话管理器和 Co。如果连接配置完成,那么您可以调用 connect() 方法来建立与设备(数据库)的物理连接。
I think you are missing some parts in OOP concepts and good design. If your code is not readable anymore - as Martin Fowler mentioned it, if your code smells - because of your tries to increase cohesion or reduce coupling (you can't remove coupling to %0 or you can't increase cohesion upto 100%. As you try this, you get a code like your connect() example above), you are on a wrong way. Because, these concepts are there to make your code more readable. There are also refactoring concepts like "extract method" to increase cohesion. Cohesion and Coupling are usually used with adjectives, "lower coupling" and "higher cohesion". How low or high they must be, the designer must decide/optimise it. By the way, if you session.connect() calls, i don't expect that the connection has to be configured. To do this, there are many other concepts like connection factory, session manager and Co. If the connection is once configured, then you can call connect() method to establish a physical connection to device (database).
我认为这不能以任何有意义的方式来回答。
正如 @Erhan 的回答所指出的,内聚和耦合是与其他措施以及设计原则(OO 和其他)“紧张”的措施。如果您忽略常识并尝试单独最大化/最小化这些措施,您最终会得到不可读的代码。
IMO,最好的方法是培养一种良好的直觉,让你的代码可读,你的设计易于理解。请注意各种措施,但如果它们与您的直觉相矛盾,请准备忽略它们。如果您不确定自己的直觉是否正确,请请更有经验的开发人员来审查您的工作。
永远记住,各种衡量标准(内聚性、耦合性、复杂性、测试覆盖率)都是经验性的,“良好的设计”和“最佳实践”也是如此。他们忽略了你试图解决的问题的现实。不要用它们作为不思考和使用你判断的借口。
I don't think this is answerable in any meaningful way.
As @Erhan's answer points out, Cohesion and Coupling are measures that are "in tension" with other measures, and with the principles of design (OO and otherwise). If you ignore common sense and attempt to max/minimize these measures in isolation, you end up with unreadable code.
IMO, the best approach is to develop a good intuition of what makes your code readable and your design comprehensible. Pay some attention to the various measures, but if they contradict your intuition, be prepared to ignore them. If you are unsure if your intuition is correct, ask a more experienced developer to review your work.
Always remember that the various measures (cohesion, coupling, complexity, test coverage) are empirical, as are "good design" and "best practice". They ignore the realities of the problem that you are trying to solve. Don't use them as an excuse for not thinking and using your judgement.