您的问题实际上有两个含义。
必须在许多类中多次重用
它可以是设计模式(可重用组件)或内存成本(类实例化)的上下文。从两种不同的角度谈:
内存成本 (我对此没有多少经验,但让我分享经验)
本节实际上仅涵盖2种实例化。
首先是静态的(或合成根中的DI实例化)
- 急切的实例化,意味着所有类将在应用程序启动时实例化
- 仅一次实例化
非静态
- 延迟实例化,意味着类仅在需要时实例化
- 每次使用一次实例化
简而言之,如果类很多,那么静态将花费很高,而如果请求很高(例如,在循环内部),则非静态将花费很高。但这不应该使您的应用程序繁重。尽管在Java /
csharp中,大多数操作都是创建对象。
类可重用性
1-巨型单片代码(一个神职人员几乎可以完成所有工作)
优点:
- 易于搜索代码(尽管还是要视情况而定),您知道每个逻辑都在那里,因此您只需要查看该大类即可
- 如果它是静态的,则可以在任何地方调用它而不必担心实例化
缺点:
- 对一种方法的任何修改都会在其他地方带来错误的风险
- 违反SRP,意味着可以出于各种原因(不仅是一种原因)更改此类
- 特别是在版本控制中,如果修改发生在单独的分支中,则很难合并,从而导致同步代码的工作量
1a /静态类/单例模式
优点:
- 易于使用
- 可以在任何地方使用(只需参考和调用即可完成)
- 不需要实例化对象
缺点:
- 难以进行单元测试(很难模拟,并且在以后的时间中,您会发现准备测试环境需要花费时间。尤其是对于数据而言)
- 如果是有状态的(有状态),则在调试期间很难确定当前状态。而且,很难确定哪个功能可以改变状态,可以随时随地改变
- 倾向于有很多参数(可能在5-11左右)
2策略模式
实际上,它的设计与3或相同
composition over inheritance。
3依赖注入
优点:
- 易于模拟和单元测试
Must be stateless
。如果类是无状态的,则调试和单元测试更加容易- 支持重构
缺点:
- 对于那些不熟悉接口的人来说很难调试(每次您重定向到方法时,它都会转到接口的方法)
- 创建将导致映射的分层
状态/无状态
我认为状态在您的应用程序设计中起着重要的规则。通常,开发人员尝试避免在业务逻辑代码中包含状态,例如:
// get dataif(request.IsDraft){ // step 1 // step 2}else{ // step 1 // step 3}开发人员倾向于将逻辑放在其他
stateless类中,或者至少将诸如以下方法:
// get dataif(request.IsDraft){ draftRequestHandler.Modify(request);}else{ publishedRequestHandler.Modify(request);}它将提供更好的可读性,并且更易于修改和单元测试。也有一种设计模式
state pattern or hierarchial state machinepattern,特别是处理这样的情况。
单一责任原则
恕我直言,如果遵循这一原则,则将带来最大的好处。优点是:
- 在版本控制中,所做的更改清楚地表明了修改了哪个类以及为什么
- 在DI中,可以连接几个较小的类,从而在使用和单元测试方面都具有灵活性
- 增加模块化,低耦合和高内聚性
TDD(测试驱动开发)
这种设计不能保证您的代码没有错误。考虑到在设计阶段花费时间和分层工作,它具有以下优点:
- 易于模拟对象以进行单元测试
- 由于单元测试和模块化,更易于重构
- 易于维护/扩展
一些有用的资源
服务定位器反模式
使用Decorator处理横切关注点
最后的想法
这些设计和策略不是决定您的应用程序结构的关键。仍然由建筑师来决定。我宁愿遵循诸如SOLID,KISS和GRASP之类的原则,而不是确定最佳的结构。据说依赖注入遵循了大多数原则,但是过多的抽象和不正确的组件设计将导致滥用单例模式。



