专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

策略设计模式用实例理解(更好的理解接口,解耦合)

  Whattodo?
  接下来我们聊一聊对象数组排序,有排序那肯定有两两比较的过程;对于对象而言,其中有很多属性方法,我们可以通过某个属性进行比较,进而实现对对象数组的排序,对于下面程序:Studentstu1newStudent(张三,12,153。4);Studentstu2newStudent(李四,14,163。4);Studentstu3newStudent(王五,13,123。4);Studentstu4newStudent(赵六,4,6。4);Student〔〕stus{stu1,stu2,stu3,stu4};复制代码
  Student类中的有参构造器中的参数分别为:姓名、年龄、身高;其中stus就是对象数组,现在我需要通过年龄对stus数组进行排序,那么我们就可以通过冒泡排序实现,具体如下:for(inti0;istus。length1;i){for(intj0;jstus。lengthi1;j){if(stus〔j〕。agestus〔j1〕。age){Studenttempstus〔j〕;stus〔j〕stus〔j1〕;stus〔j1〕temp;}}}复制代码
  通过上述代码我们就可以将对象数组通过年龄进行排序;在上述代码中比较年龄就是一个比较策略,我们可以改变策略,比如比较身高,那么我们就需要让对象调用属性height。Howtodo?
  承接上述,我们就以对象数组排序来慢慢理解策略设计模式;
  首先我们创建User类,存放属性和方法,做为实例化对象的原始类;publicclassUser{创建属性privateStringname;privateintage;privateintheight;创建构造方法(若自己建立有参构造,须把无参构造加上)publicUser(){}publicUser(Stringname,intage,intheight){this。namename;this。ageage;this。heightheight;}创建getset方法publicStringgetName(){returnname;}publicvoidsetName(Stringname){this。namename;}publicintgetAge(){returnage;}publicvoidsetAge(intage){this。ageage;}publicintgetHeight(){returnheight;}publicvoidsetHeight(intheight){this。heightheight;}重写toString()方法OverridepublicStringtoString(){returnUser{namename,ageage,heightheight};}}复制代码
  创建Client类,用来实例化对象,封装对象数组,然后实现通过年龄进行进行对象数组排序;publicclassClient{主函数中创建对象,封装对象数组publicstaticvoidmain(String〔〕args){创建User对象Useruser1newUser(张三,12,153);Useruser2newUser(李四,14,163);Useruser3newUser(王五,13,133);Useruser4newUser(赵六,11,143);封装对象数组User〔〕users{user1,user2,user3,user4};通过年龄对数组进行正向排序for(inti0;iusers。length1;i){for(intj0;jusers。lengthi1;j){if(users〔j〕。getAge()users〔j1〕。getAge()){Usertempusers〔j〕;users〔j〕users〔j1〕;users〔j1〕temp;}}}输出查看对象数组是否排序成功System。out。println(Arrays。toString(users));}}复制代码
  结果如下:
  存在问题:我们可以看到已经排序成功;但是上述代码存在的问题是【将实现的细节暴露给了客户,并且比较也应该更面向对象一点】
  解决方法:对于比较来说,我们可以改进比较方法,对比较进行封装,使得改变比较策略,而不复写代码;在此我们可以联想到equals()方法,因此我们可以抽离出一个让两个User对象进行比较的接口Comparable,然后让User实现该接口,从而完善Client中的比较细节;
  创建Comparable接口,定义compare()方法;publicinterfaceComparable{封装比较方法,传入User对象,实现与调用对象的比较Integercompare(Objectobject);}复制代码
  更新User类,让其继承Comparable接口,实现compare()方法;publicclassUserimplementsComparable{同之前的一样,就是增加了下面的这个方法返回两个对象的比较的结果OverridepublicIntegercompare(Objectobject){如果传进来的是一个User类型的对象,那么再继续往下比,否则直接返回nullif(objectinstanceofUser){首先将传进来的Object类型转换为User类型Useruser(User)object;返回比较的结果returnthis。getAge()user。getAge();}returnnull;}}复制代码
  Clien类中的排序方法中的比较就变得更加简洁,users〔j〕。compare(users〔j1〕)通过年龄对数组进行正向排序for(inti0;iusers。length1;i){for(intj0;jusers。lengthi1;j){if(users〔j〕。compare(users〔j1〕)0){Usertempusers〔j〕;users〔j〕users〔j1〕;users〔j1〕temp;}}}复制代码
  上述这种写法的好处:让所有对象拥有了可比较的能力(这也是接口的好处),并且将具比的东西转给了对象;
  问题:如果按其他属性去排序,也就是改变排序策略,那么还是得去修改User中的compaer方法,这样还是不符合开闭原则,且细节还是暴露在外边,扩展性也差;
  截至目前的两个问题:细节暴露在Client类中,这就很不面向对象;(宗旨:一个方法解决一个问题,而不是一坨代码解决一个问题,即单一原则)修改比较策略时还得改动源代码,这违反了开闭原则;对于第一个问题
  根据单一原则,我们构建UserSorter类,实现排序方法;publicclassUserSorter{创建实现对象排序功能的方法sortpublicvoidsort(User〔〕users){通过年龄对数组进行正向排序for(inti0;iusers。length1;i){for(intj0;jusers。lengthi1;j){if(users〔j〕。compare(users〔j1〕)0){Usertempusers〔j〕;users〔j〕users〔j1〕;users〔j1〕temp;}}}}}复制代码
  因此我们可将Client中实现比较的代码转换为userSorter。sort(users)publicclassClient{主函数中创建对象,封装对象数组publicstaticvoidmain(String〔〕args){创建User对象Useruser1newUser(张三,12,153);Useruser2newUser(李四,14,163);Useruser3newUser(王五,13,133);Useruser4newUser(赵六,11,143);封装对象数组User〔〕users{user1,user2,user3,user4};创建UserSorter对象UserSorteruserSorternewUserSorter();调用UserSorter中的sort方法实现排序userSorter。sort(users);输出查看对象数组是否排序成功System。out。println(Arrays。toString(users));}}复制代码
  截至目前,我们就将实现细节屏蔽在Usersorter类中,并且让排序方法面向对象实现;对于第二个问题
  既然在改变比较策略时不想修改User类中的代码,那么我们就不让User类去实现Comparable接口;然后比较器UserSorer中的sort方法就得改!如果我们将sort中的比较策略写死,比如就写比较年龄,那我们改变比较策略的时候,比如想比较身高,那么就一定会对代码进行修改,但我们要对修改关闭,因此我们可以将User中的比较方法抽出去,让其不具备比较的能力;那么我们就可以想到建立一个类,让其拥有比较两个对象的能力,最终我们只需要将users〔j〕,users〔j1〕,做为参数传入建立夫人那个类中的哪个方法中,最终让它返回比较的结果就行;
  这样就对User本身无侵入性,就实现了不改动User代码;
  我们现在定义这个类叫做Comparator,其中比较两个对象的方法为compare(Useruser,Useruser1);publicclassComparator{publicIntegercompare(Useruser,Useruser1){returnuser。getAge()user1。getAge();}}复制代码
  那么UserSorter中的sort方法就需要加参数,改进比较;publicclassUserSorter{创建实现对象排序功能的方法sortpublicvoidsort(User〔〕users,Comparatorcomparator){通过年龄对数组进行正向排序for(inti0;iusers。length1;i){for(intj0;jusers。lengthi1;j){if(comparator。compare(users〔j〕,users〔j1〕)0){Usertempusers〔j〕;users〔j〕users〔j1〕;users〔j1〕temp;}}}}}复制代码
  Client中在调用sort方法时就直接将比较器类Comparatornew进去就可;调用UserSorter中的sort方法实现排序userSorter。sort(users,newComparator());复制代码
  截至目前,我们这样写还是违背了开闭原则,【在这里我们定义方法时,参数要面向抽象、面向接口,这样扩展性强,如果面向具体实现类,那只能实现写死的那个类,扩展性就很差】;所以我们将sort(User〔〕users,Comparatorcomparator)中的第二个参数试着变成接口:
  将Comparator改为接口;publicinterfaceComparator{Integercompare(Useruser,Useruser1);}复制代码
  创建CompareAgeStrategy类实现Comparator接口,作用为比较年龄策略;publicclassCompareAgeStrategyimplementsComparator{publicIntegercompare(Useruser,Useruser1){returnuser。getAge()user1。getAge();}}复制代码
  这样写的话,我们在UserSorter中的sort方法里传入的就是接口,那么我们在Client类中调用sort方法时传入的参数就可以new具体的比较策略,比如:实现了年龄策略比较userSorter。sort(users,newCompareAgeStrategy());复制代码
  那么我们如果想比较身高的话,那就可以扩展一个比较身高策略类,传参数时直接new比较身高策略类即可,这样就满足了不对源代码进行修改,只在源代码上进行扩展,这就满足了开闭原则,整个过程也诠释了策略设计模式;
  创建CompareHeightStrategy类实现Comparator接口,作用为比较身高策略;publicclassCompareHeightStrategyimplementsComparator{OverridepublicIntegercompare(Useruser,Useruser1){returnuser。getHeight()user1。getHeight();}}复制代码
  修改Client中调用sort方法时穿的参数;实现了身高策略比较userSorter。sort(users,newCompareHeightStrategy());复制代码
  最终结果:
  至此,Client就只需要享受策略就ok;总结从开始到最终做的工作就是一个解耦合的过程;再定义一个方法时,其中的参数需要面向抽象或者接口,这样扩展性就强;若面向具体实现类,扩展性就会变差;

当元PLUS遇到AIONY,刀片电池和弹匣电池各有什么优势?随着社会的发展和全球追求碳中和社会背景,新能源汽车越来越受到广大消费者的青睐,预算价格14万左右想选择一台性价比比较高的新能源车型,那么比亚迪元PLUS和广汽AIONY算是关注度比协鑫集成收关注函,要求说明乐山光伏电池项目投产未达预期原因及实施风险协鑫集成10月28日收到深交所关注函,对公司拟投资80亿元在芜湖市湾沚区投资建设20GWTOPCon光伏电池及配套产业生产基地项目一事表示关注。深交所要求公司详细说明乐山光伏电池项一粒难求终于刹车最近片仔癀第三季度净利润下滑近两成的消息,扰动了资本市场,直接引起市场的恐慌。2021年年中,片仔癀锭剂突然在市场中走红,终端零售价每粒被炒至上千元,且出现一粒难求局面。为了抑制市日媒车载电池需求增长刺激锂价创新高据日本经济新闻10月28日报道,作为电动汽车车载电池主要原料的金属锂指标性价格再创新高。报道称,电动汽车产量迅速扩大,尤其是低价位电动汽车用电池的需求不断增长。用途仅限于生产高级电重磅数据密集发布多部门四天两文促外资丨一周热点回顾主要经济数据出炉,三季度GDP增3。9本周进入重磅经济数据发布周。国家统计局财政部海关总署等多部门相继发布了三季度主要经济数据。GDP前三季度国内生产总值870269亿元,同比增长Android前沿技术JetpackCompose简介JetpackCompose是一款新型工具包,旨在帮助简化界面开发。该工具包将响应式编程模型与简洁易用的Kotlin编程语言相结合,并采用完全声明式的代码编写方式,让您可以通过山东省政府出台实施意见,重点培育这十大平台经济生态体系山东省人民政府关于加快推动平台经济规范健康持续发展的实施意见各市人民政府,各县(市区)人民政府,省政府各部门各直属机构,各大企业,各高等院校为深入贯彻落实习近平总书记关于推动平台经光峰科技前三季度营收18。76亿元同比增长12。96中证网讯(王珞)10月28日晚,光峰科技发布2022年三季报,报告显示,前三季度公司实现营业收入18。76亿元,同比增长12。96归属于上市公司股东的净利润为9135。62万元经营巨人杀手王晗能否再次上演奇迹,多项数据处于下风很难扳倒领头羊CBA联赛进入最后几轮比赛似乎迎来高潮,无论是复仇之战还是扭转连败结局都让比赛质量提升许多,激烈的对抗更让比赛过程增色不少。今日五场大战,四川对阵福建都渴望拿下对手止住连败,青岛对影像旗舰机220W快充,RdemiNote12探索版买不买?上一期为大家讲解了三星新款机皇W23和W23Flip,那么今天就位大家讲一下Rdemi刚刚发布的Note12探索版。作为RdemiNote系列今年的第二代产品,RdemiNote1小米突然发布新机,2亿像素210W快充,仅售1199元起小米突然发布了一款新机,而且性价比很高,仅售1199元起,它就是红米Note12,这次的RedmiNote12最大的亮点就是影像,一个是Note12pro的2亿像素,另一个是Not
日本J2球队神奇夺冠!42岁队长点射进亚冠,连克5支顶级联赛队伍日本足球发展至今,发生过不少神奇的事情,原本觉得没什么还能让人惊讶的了。然而,来自J2联赛的球队甲府风林上演神奇经历引人瞩目,一路连克5支J1球队豪夺冠军,从而闯入下赛季亚冠!10赵继伟独自带队,辽宁队将终结山西队三连胜,付豪韩德君统治内线辽宁队本赛季在缺少张镇麟与大外援莫兰德依旧取得赛季不败的四连胜,足以证明这支辽宁队韧性十足,哪怕球队核心郭艾伦因私自外出被禁赛6场,辽宁队还是顶住压力拿下广州队取得四连胜,在缺少三澳门冠军赛第2日赛程国乒3大主力登场,张本智和冲击16强北京时间2022年10月20日,WTT澳门冠军赛进入第2比赛日,男单和女单第一轮继续进行,国乒三位主力樊振东孙颖莎王曼昱亮相,樊振东迎战直板好手黄镇廷,孙颖莎对阵巴西选手高桥布鲁娜广东1分惜败让杜峰无奈,赵睿又不冷静,内线新人表现还不如苏伟2022年10月19日,广东9596负于山东队,杜峰把所有的战术都用上了,奈何山东队太高了,即使是大前锋都比广东的首发中锋高。易建联今天没有出场比赛,内线真是无人可用,老将任骏飞任天才与努力这个世界的神奇之处在于它的多样性,它从来不缺乏天才,更不缺乏凡夫俗子。你认为你已经够牛逼了,但在社会的某处,总有跟你一样牛逼甚至比你还牛逼的人存在!蒋介石四十岁时横扫各路枭雄,以为湖人新闻三巨头合砍77分,14分分差爆冷!哈姆4后卫阵容遭批前言鉴于湖人队在季前赛的糟糕表现,与勇士队的揭幕战,似乎很有可能是一场非常不平衡的,勇士队单方面的碾压赛。虽然詹姆斯,威少,浓眉在赛前都出现了部分身体方面的不适,并且被列入出战可疑年薪4700万,场均10。5分!杜兰特看透了,你只是不适合湖人和老詹湖人今夏的操作,雷声大雨点小,最终威少留在湖人,只是湖人管理层不愿意轻易拿出27年和29年两个首轮签。季前赛,湖人1胜5负,唯一一场胜利来自于对阵勇士,此外30分惨败国王,47分惨TWS芯片黑马物奇拟实现头部品牌企业全覆盖集微网报道,时间倒退至2016年,苹果首款Airpods的发布带火了TWS耳机,2018年2021年迎来爆发式增长,TWS耳机出货量飙升超6倍,此时品牌和白牌产业链基本上都赚得盆满80年代,山西老农拿出一张1100万的欠条,专家你父亲是谁?如果您喜欢这篇文章,请点击右上方的关注。感谢您的支持和鼓励,希望能给您带来舒适的阅读体验。家国危难风雨飘摇之际,总有许多热血志士挺身而出,他们不求回报,只希望能够为新时代的早日到来山西省跨境电商9810首单落地本报讯山西上卓玻璃制品有限公司出口美国长滩的货物日前顺利通关,这是我省首单通过跨境电商9810(跨境电商出口海外仓)方式申报通关的出口货物。连日来,隶属于华远国际陆港集团有限公司的人这一生只有3次改变命运的机会20221020相信命运的人,跟随命运走。不相信命运的人,领着命运换个方向走。真正改变命运的,并不是我们的机遇,而是我们的态度。不论如今的你在人生的哪个阶段,请不要放弃改变名自己的
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网