大龄程序员谈架构经验内行看门道
前言
孔乙己显出极高兴的样子,将两个指头的长指甲敲着柜台,点头说:对呀,对呀!。。。。。。回字有四样写法,你知道么?
大家好,我是44岁的大龄程序员码农阿峰。阿峰从事编程二十年了,虽然没有成为架构师,却也用过很多种架构。我觉得一招鲜走遍天,架构师常用的那几招我还是会的,听我来说道说道。我以为至少有这几招:模板方法设计模式反射不重复造轮子,集众家所长架构经验总结
1)。模板方法设计模式的运用
在一个方法中定义了一个算法的骨架或者步骤,而将一些步骤延迟到子类中去实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某一些步骤。父类:namespaceRepository{summary数据库存储泛型基类summarytypeparamnameTtypeparampublicclassBaseRepositoryT:SimpleClientTwhereT:class,new(){publicITenantitenantnull;多租户事务publicBaseRepository(ISqlSugarClientcontextnull):base(context){通过特性拿到ConfigIdvarconfigIdtypeof(T)。GetCustomAttributeTenantAttribute()?。configId;if(configId!null){ContextDbScoped。SugarScope。GetConnectionScope(configId);根据类传入的ConfigId自动选择}else{Contextcontext??DbScoped。SugarScope。GetConnectionScope(0);没有默认db0}itenantDbScoped。SugarScope;设置租户接口}regionaddsummary插入实体summaryparamnametparamreturnsreturnspublicintAdd(Tt){returnContext。Insertable(t)。IgnoreColumns(true)。ExecuteCommand();}publicintInsert(ListTt){returnContext。Insertable(t)。ExecuteCommand();}publicintInsert(Tparm,ExpressionFuncT,objectiClumnsnull,boolignoreNulltrue){returnContext。Insertable(parm)。InsertColumns(iClumns)。IgnoreColumns(ignoreNullColumn:ignoreNull)。ExecuteCommand();}publicIInsertableTInsertable(Tt){returnContext。InsertableT(t);}endregionaddregionupdatepublicIUpdateableTUpdateable(Tentity){returnContext。Updateable(entity);}publicintUpdate(Tentity,boolignoreNullColumnsfalse){returnContext。Updateable(entity)。IgnoreColumns(ignoreNullColumns)。ExecuteCommand();}publicintUpdate(Tentity,ExpressionFuncT,objectexpression,boolignoreAllNullfalse){returnContext。Updateable(entity)。UpdateColumns(expression)。IgnoreColumns(ignoreAllNull)。ExecuteCommand();}summary根据实体类更新指定列eg:Update(dept,itnew{it。Status},fdepts。Contains(f。DeptId));只更新Status列,条件是包含summaryparamnameentityparamparamnameexpressionparamparamnamewhereparamreturnsreturnspublicintUpdate(Tentity,ExpressionFuncT,objectexpression,ExpressionFuncT,boolwhere){returnContext。Updateable(entity)。UpdateColumns(expression)。Where(where)。ExecuteCommand();}publicintUpdate(SqlSugarClientclient,Tentity,ExpressionFuncT,objectexpression,ExpressionFuncT,boolwhere){returnclient。Updateable(entity)。UpdateColumns(expression)。Where(where)。ExecuteCommand();}summarysummaryparamnameentityparamparamnamelistparamparamnameisNull默认为trueparamreturnsreturnspublicintUpdate(Tentity,Liststringlistnull,boolisNulltrue){if(listnull){listnewListstring(){CreateBy,Createtime};}returnContext。Updateable(entity)。IgnoreColumns(isNull)。IgnoreColumns(list。ToArray())。ExecuteCommand();}summary更新指定列eg:Update(ww。NoticeIdmodel。NoticeId,itnewSysNotice(){UpdatetimeDateTime。Now,Title通知标题});summaryparamnamewhereparamparamnamecolumnsparamreturnsreturnspublicintUpdate(ExpressionFuncT,boolwhere,ExpressionFuncT,Tcolumns){returnContext。UpdateableT()。SetColumns(columns)。Where(where)。RemoveDataCache()。ExecuteCommand();}endregionupdatepublicDbResultboolUseTran(Actionaction){try{varresultContext。Ado。UseTran(()action());returnresult;}catch(Exceptionex){Context。Ado。RollbackTran();Console。WriteLine(ex。Message);throw;}}publicIStorageableTStorageable(Tt){returnContext。StorageableT(t);}publicIStorageableTStorageable(ListTt){returnContext。Storageable(t);}summarysummaryparamnameclientparamparamnameaction增删改查方法paramreturnsreturnspublicDbResultboolUseTran(SqlSugarClientclient,Actionaction){try{varresultclient。AsTenant()。UseTran(()action());returnresult;}catch(Exceptionex){client。AsTenant()。RollbackTran();Console。WriteLine(ex。Message);throw;}}publicboolUseTran2(Actionaction){varresultContext。Ado。UseTran(()action());returnresult。IsSuccess;}regiondeletepublicIDeleteableTDeleteable(){returnContext。DeleteableT();}summary批量删除summaryparamnameobjparamreturnsreturnspublicintDelete(object〔〕obj){returnContext。DeleteableT()。In(obj)。ExecuteCommand();}publicintDelete(objectid){returnContext。DeleteableT(id)。ExecuteCommand();}publicintDeleteTable(){returnContext。DeleteableT()。ExecuteCommand();}publicboolTruncate(){returnContext。DbMaintenance。TruncateTableT();}endregiondeleteregionquerypublicboolAny(ExpressionFuncT,boolexpression){returnContext。QueryableT()。Where(expression)。Any();}publicISugarQueryableTQueryable(){returnContext。QueryableT();}public(ListT,int)QueryableToPage(ExpressionFuncT,boolexpression,intpageIndex0,intpageSize10){inttotalNumber0;varlistContext。QueryableT()。Where(expression)。ToPageList(pageIndex,pageSize,reftotalNumber);return(list,totalNumber);}public(ListT,int)QueryableToPage(ExpressionFuncT,boolexpression,stringorder,intpageIndex0,intpageSize10){inttotalNumber0;varlistContext。QueryableT()。Where(expression)。OrderBy(order)。ToPageList(pageIndex,pageSize,reftotalNumber);return(list,totalNumber);}public(ListT,int)QueryableToPage(ExpressionFuncT,boolexpression,ExpressionFuncT,objectorderFiled,stringorderBy,intpageIndex0,intpageSize10){inttotalNumber0;if(orderBy。Equals(DESC,StringComparison。OrdinalIgnoreCase)){varlistContext。QueryableT()。Where(expression)。OrderBy(orderFiled,OrderByType。Desc)。ToPageList(pageIndex,pageSize,reftotalNumber);return(list,totalNumber);}else{varlistContext。QueryableT()。Where(expression)。OrderBy(orderFiled,OrderByType。Asc)。ToPageList(pageIndex,pageSize,reftotalNumber);return(list,totalNumber);}}publicListTSqlQueryToList(stringsql,objectobjnull){returnContext。Ado。SqlQueryT(sql,obj);}summary根据主值查询单条数据summaryparamnamepkValue主键值paramreturns泛型实体returnspublicTGetId(objectpkValue){returnContext。QueryableT()。InSingle(pkValue);}summary根据条件查询分页数据summaryparamnamewhereparamparamnameparmparamreturnsreturnspublicPagedInfoTGetPages(ExpressionFuncT,boolwhere,PagerInfoparm){varsourceContext。QueryableT()。Where(where);returnsource。ToPage(parm);}publicPagedInfoTGetPages(ExpressionFuncT,boolwhere,PagerInfoparm,ExpressionFuncT,objectorder,OrderByTypeorderEnumOrderByType。Asc){varsourceContext。QueryableT()。Where(where)。OrderByIF(orderEnumOrderByType。Asc,order,OrderByType。Asc)。OrderByIF(orderEnumOrderByType。Desc,order,OrderByType。Desc);returnsource。ToPage(parm);}publicPagedInfoTGetPages(ExpressionFuncT,boolwhere,PagerInfoparm,ExpressionFuncT,objectorder,stringorderByType){returnGetPages(where,parm,order,orderByTypedesc?OrderByType。Desc:OrderByType。Asc);}summary查询所有数据(无分页,请慎用)summaryreturnsreturnspublicListTGetAll(booluseCachefalse,intcacheSecond3600){returnContext。QueryableT()。WithCacheIF(useCache,cacheSecond)。ToList();}endregionquerysummary此方法不带output返回值varlistnewListSugarParameter();list。Add(newSugarParameter(ParaName,ParaValue));inputsummaryparamnameprocedureNameparamparamnameparametersparamreturnsreturnspublicDataTableUseStoredProcedureToDataTable(stringprocedureName,ListSugarParameterparameters){returnContext。Ado。UseStoredProcedure()。GetDataTable(procedureName,parameters);}summary带output返回值varlistnewListSugarParameter();list。Add(newSugarParameter(ParaName,ParaValue,true));outputlist。Add(newSugarParameter(ParaName,ParaValue));inputsummaryparamnameprocedureNameparamparamnameparametersparamreturnsreturnspublic(DataTable,ListSugarParameter)UseStoredProcedureToTuple(stringprocedureName,ListSugarParameterparameters){varresult(Context。Ado。UseStoredProcedure()。GetDataTable(procedureName,parameters),parameters);returnresult;}}summary分页查询扩展summarypublicstaticclassQueryableExtension{summary读取列表summarytypeparamnameTtypeparamparamnamesource查询表单式paramparamnameparm分页参数paramreturnsreturnspublicstaticPagedInfoTToPageT(thisISugarQueryableTsource,PagerInfoparm){varpagenewPagedInfoT();vartotal0;page。PageSizeparm。PageSize;page。PageIndexparm。PageNum;page。Resultsource。OrderByIF(!string。IsNullOrEmpty(parm。Sort),34;{parm。Sort}{(parm。SortType。Contains(desc)?desc:asc)})。ToPageList(parm。PageNum,parm。PageSize,reftotal);page。TotalNumtotal;returnpage;}}}子类:〔AppService(ServiceLifetimeLifeTime。Transient)〕publicclassGenDemoRepository:BaseRepositoryGenDemo{region业务逻辑代码endregion}
现在大家都学精了,都使用泛型基类来简化重复的代码,标准的架构还是按经典的三层架构标准来搭建。这个是基本功,不用说太细。
2)。反射
反射:是。NetFramework和。NetCore提供的一个帮助类库,可以访问dll的metadata,并且使用它。
反射反射,程序员的快乐summary注册引用程序域中所有有AppService标记的类的服务summaryparamnameservicesparampublicstaticvoidAddAppService(thisIServiceCollectionservices){varassembliesAppDomain。CurrentDomain。GetAssemblies();string〔〕clsnewstring〔〕{Topaut。Repository,Topaut。Service,Topaut。Tasks};foreach(varitemincls){AssemblyassemblyAssembly。Load(item);Register(services,assembly);}}privatestaticvoidRegister(IServiceCollectionservices,Assemblyassembly){foreach(vartypeinassembly。GetTypes()){varserviceAttributetype。GetCustomAttribute();if(serviceAttribute!null){varserviceTypeserviceAttribute。ServiceType;情况1适用于依赖抽象编程,注意这里只获取第一个if(serviceTypenullserviceAttribute。InterfaceServiceType){serviceTypetype。GetInterfaces()。FirstOrDefault();}情况2不常见特殊情况下才会指定ServiceType,写起来麻烦if(serviceTypenull){serviceTypetype;}switch(serviceAttribute。ServiceLifetime){caseLifeTime。Singleton:services。AddSingleton(serviceType,type);break;caseLifeTime。Scoped:services。AddScoped(serviceType,type);break;caseLifeTime。Transient:services。AddTransient(serviceType,type);break;default:services。AddTransient(serviceType,type);break;}Console。WriteLine(34;注册:{serviceType});}else{Console。WriteLine(34;注册:{serviceType});}}}}
官方各种Service注入IOC容器都是手写,框架作者利用反射实现了减少大量繁琐的固定写法,对于普通项目而言,反射的性能损耗微不足道的。
3)。不重复造轮子集众家所长
有时程序员喜欢浪费生命去重复造轮子,如果是为了学习一次怎么造轮子是值得肯定的。否则就是吃饱了没事干闲的。现在是最好的时代(好多开源组件可用),也是最坏的时代(行业太卷)。框架作者使用了糖果大数据的开源组件SqlSugar来实现多数据库类型的支持,还有多租户,读写分离,分表分库这些数据库层面的数据存储方案。实现前后端分离参考了一些其他的优秀Vue实现的Admin框架。
在线体验官方文档:http:www。izhaorui。cndocvue3。x版本体验:http:www。izhaorui。cnvue3vue2。x版本体验:http:www。izhaorui。cnadmin账号密码:admin123456
https:gitee。comizoryZrAdminNetCore
泰国人妖评价各国游客日本人礼貌,韩国人爱占便宜在天气好的时候很多游客都喜欢到泰国游玩观光,通过旅游去欣赏泰国当地的热带宜人风光和开拓见识,不少游客还想要去感受一下泰国的夜生活以及体验当地的各种风俗文化。泰国消费性价比高,能够花
微软取消1美元的XboxGamePass新用户优惠环球网科技综合报道3月27日消息,据微软方面消息称,微软已经停止了以1美元的价格获得第一个月的GamePass的促销活动,新订阅者不再享受此促销优惠。微软已经在多个国家和地区取消了
变废为宝的蛋白纤维原标题变废为宝的蛋白纤维近期,中国科学院大学研究团队制备出一款具备良好的抗冰能力和低温机械性能的蛋白纤维。值得一提的是,该蛋白纤维即使20至40,也能保持高刚度和韧性。这种新型蛋白
不揉面的懒人葱花饼,2分钟出一张,外酥里软层次丰富,凉了不硬头条创作挑战赛我觉得现在离不开面食,真是太好吃了。面食有一个很重要的特点,那就是吃着好消化易吸收。吃的时候很饱,但是很快就饿了,那就是它太好消化了,如果易胖体质吃面食,那胖的更快。
12道开胃下饭的菜谱,欢迎大家在家学起来!香油炝茭瓜原料茭瓜250克。调料植物油盐味精白糖香油红油花椒油干椒段花椒。做法1将茭瓜去皮洗净,用滚刀法切成转头形。2锅内放植物油,烧至七成热,放入茭瓜过油至七成熟,倒入漏勺中,沥
清新爽口的家常美食,价格实惠,鲜嫩更下饭!韭菜是一种常见的蔬菜,营养丰富,有益于人体健康。韭菜中含有丰富的维生素纤维素等多种营养成分。这些成分能够增强消化功能缓解便秘益肝健胃维护人体的免疫功能。韭菜可以烹饪出多种美味菜肴,
甲流不可怕,可怕的是人心这几天,甲流如同一阵风扑面而来,大街小巷说的最多的就是我中招了。医院诊所都人满为患,特别是孩子最多。新冠大家都还记忆犹新,那是大家对它不了解,满是焦虑恐惧。而经历过这么多了,我们应
河南多地调整住房公积金政策郑州市民呼吁全面推行商转公政策大河报豫视频记者韩懿亭近日,河南多地市陆续调整住房公积金政策。比如,驻马店力推带押过户政策,公积金最高贷款额度为50万元南阳公积金新政将二套房首付比例降至20除此之外,记者发现,不
豫东明珠河南开封尉氏县历史开讲老家河南开封尉氏尉氏县,隶属开封市,位于河南省中东部。东接通许扶沟,西临新郑,南依鄢陵长葛,北靠开封祥符区中牟。春秋为郑国之东鄙(指边远的地方),为囚禁尚未定刑的犯人之别狱
韩联社韩国去年新生儿中头胎占比创新高低生育率问题更为加剧据韩联社报道,韩国统计厅26日发布的一份数据显示,去年诞生的婴儿中,头胎为15。6万人,在整体出生婴儿人数(24。9万人)中占比62。7,创1981年开始相关统计以来的最高纪录。这
患慢病不能让午睡背锅来源生命时报研究发现,小睡有助恢复精力,但睡得太长可能增加糖尿病心脑血管疾病风险受访专家北京大学公共卫生学院流行病与卫生统计学系副教授余灿清本报记者张芳讲究养生的人大多知道子午觉晚