Status:
Fendy和Glen Best的答案同样可以接受并受到我的尊重,但由于我可以接受并获得赏金,我选择了Fendy的答案
Scenario:
如果我某些代码 多次重复使用 很多类(很少有明显的次要参数更改)和并发线程,采用哪种方法?
必须重用的代码可以是任何理智的东西(适当考虑静态和非静态上下文和方法制作技术)。它可以是一个算法,一个DB方法做连接,操作,关闭。任何东西。
制作一些类MyMethods.class
和将所有这些方法放入其中。
1.A。使方法 static
并直接调用(由所有类和并发线程)MyMethods.someMethod();
1.B。在<{>}
使用https://en.wikipedia.org/wiki/Strategy_pattern中所述的策略模式(此处附带的代码)。
non-static
有些人会说单元测试 http://en.wikipedia.org/wiki/Unit_testing 不可能这种做法会让在换出时遇到麻烦后者。如果您想测试您的课程并使用依赖的模拟版
1.A。 并发调用或多个类会有任何问题吗?特别是在instantiate
只是一个例子?
1.B。我认为这会产生太多的内存负载,因为整个类多次MyMethods mm = MyMethods(); mm.someMethod();
只需调用一两个方法
这是我的头脑,解释那个和/或任何优点/缺点
我不想要在上下文中使用框架来解决这个问题。这就是我的想法,请解释一下这个问题和/或任何优点/缺点
等待任何其他策略或建议(如果有)。
Problems:
请回答您是否有经验并深入了解其含义,并能全面地了解您的答案,帮助我和整个社区!
JDBC static methods
instanticated
答案 0 :(得分:8)
你的问题实际上有两个含义。
必须在许多类中多次重复使用
它可以是设计模式(可重用组件)或内存开销(类实例化)的上下文。从两个不同的角度讲话:
此部分实际上仅涵盖了2种实例化。
首先是静态(或组合根中的DI实例化)
<强>非静态强>
简而言之,如果类很多,静态将花费很高,如果请求很高,静态将花费很高(例如,在for循环内)。但它不应该使你的应用程序繁重。 java / csharp中的大多数操作都是创建对象。
1 - 巨型单片代码(一个上帝级别能够做几乎所有事情)
优点:
缺点:
1a /静态类/单例模式
优点:
缺点:
关于静态类的一些观点:see this question
2策略模式
实际上这与3或composition over inheritance
具有相同的设计。
3依赖注入
优点:
Must be stateless
。如果类是无状态的,则更容易调试和单元测试缺点:
我认为各州在您的应用程序设计中起着重要作用。通常开发人员会尝试避免在业务逻辑代码中使用状态,例如:
// get data
if(request.IsDraft){
// step 1
// step 2
}
else{
// step 1
// step 3
}
开发人员倾向于将逻辑放在其他stateless
类中,或者至少包括以下方法:
// get data
if(request.IsDraft){
draftRequestHandler.Modify(request);
}
else{
publishedRequestHandler.Modify(request);
}
它将提供更好的可读性,并且更容易进行修改和单元测试。还有一种设计模式state pattern or hierarchial state machine pattern
,特别是处理这种情况。
此设计不保证您的代码没有错误。考虑到在设计阶段和分层工作中花费时间,它具有以下好处:
Using Decorator for cross-cutting concern
我的2美分:
The benefit of using interface (also apply for composition ofer inheritance)
Doing top down design / DI design
这些设计和策略不是决定您的应用程序结构的关键。它仍然是决定它的建筑师。我更喜欢遵循一些原则,如SOLID,KISS和GRASP,而不是决定什么是最好的结构。据说依赖注入遵循这些原则中的大多数原则,但过多的抽象和不正确的组件设计会导致单独模式的误用。
答案 1 :(得分:3)
1.A。使方法静态并直接调用(由所有类和并发线程)作为MyMethods.someMethod();
1.B。使方法非静态并且在调用它们时,通过MyMethods mm = MyMethods()实例化整个类; mm.someMethod();
这两者之间的选择取决于MyMethods.class
的功能。如果MyMethods
应该是无状态的,那么采用static
方法是一种很好的方法。否则,如果一个方法调用依赖于另一个,MyMethods
具有状态(即非最终字段),则使用第二个选项。
使用https://en.wikipedia.org/wiki/Strategy_pattern中所述的策略模式(此处随附的代码)。
如果要为不同目的使用不同的类扩展MyMethods
,并且根据您的上下文选择要运行的代码,请使用此模式。正如 wiki 所说,如果您在运行时之前不知道要使用的算法(取决于某些条件),这就是要走的路。根据您的MyMethods
规范,您没有这样的问题。
中所述的依赖注入
与上述答案相同。 依赖注入的内容是控制反转。使用MyMethods
的类不知道MyMethods
的实际实现,但实际实现的注入被委托给某个更高级别的权限。它从将要使用它的上下文中抽象出外部依赖项。同样,如果MyMethods
是无状态和常量(没有计划改变,并且类中的方法的行为不依赖于它们被使用的上下文),你不需要这些模式,因为它只是意味着过度工程。
如果MyMethods
的逻辑取决于运行它们的上下文,我会得出结论,你应该使用策略或 DI 模式。如果这是不变的(例如,Java的Math
类不关心谁或者在什么情况下有人调用sqrt()
,max()
或pow()
)那么静态方法就是可行的方法。
关于问题:
使用MyMethods
static
方法时,您所说的问题不存在。您将不得不测试您的方法是否为特定参数返回正确的值,就是这样。我不相信在策略模式中测试Strategy
的实际实现或通过依赖注入注入的接口实现会有更多麻烦。可能更难的是测试使用策略的类,因为有时候重新创建特定策略将被执行的上下文并不容易,因为它通常取决于用户输入,但这绝对不是不可能的。就我而言,依赖注入非常适合测试,因为你可以将测试中的单元与可以轻松模拟的依赖项分开。
答案 2 :(得分:3)
主要问题:代码重用
如果我有一些代码必须在很多类中重复使用很多次(很少有明显的次要参数更改)和并发线程,那么采用哪种方法?
因为你没有考虑任何削减和口交,我认为你的意思是:
......许多班级多次重复使用......
你提出的问题并不特别或具体。代码在单个应用内或多个应用中重复使用是很常见的。 常见答案:使用面向对象的设计/编程。将代码放在一个类中,创建一个对象作为实例,调用该对象......
1a上。通过静态方法重用:
使方法静态并直接调用(由所有类和并发线程)MyMethods.someMethod()
1b中。通过非静态方法重用,使用对象实例化:
使方法非静态并且在调用它们时,通过MyMethods实例化整个类mm = MyMethods(); mm.someMethod();
使用策略模式
策略模式可以是良好的实践。但它与你的整体问题没什么关系。策略模式用于特定原因 - 交换算法/处理逻辑的实现&#34;即时&#34;不影响来电者。
使用依赖注入
出于以下原因使用依赖注入:
如果使用得当,这可能是非常好的做法。在您的情况下,这只能在选项1b下适用。依赖注入是关于对象实例化和提供变量的。
问题:
有些人会说单位测试不可能
1a上。见上文
1b中。内存负载
我认为它会产生太多的内存负载,因为整个类只需调用一两个方法即可多次即时显示
一个小问题。根据每个对象实例(实例变量)中的数据,每个对象实例可以小到十几个字节或大到兆字节 - 但通常倾向于低端(通常<1kB)。每次实例化类时,都不会复制类代码本身的内存消耗。
当然,根据您的要求,最大限度地减少对象的数量是一种很好的做法 - 如果您已有可用的实例,请不要创建新的实例。创建更少的对象实例并在整个应用程序中共享它们 - 将它们传递给构造函数方法和setter方法。依赖注入是一种自动共享对象实例的好方法。没有将它们传递给构造函数/ setter。
见上文
见上文