zoukankan      html  css  js  c++  java
  • 面向接口编程思想与实现可维护的代码 (一)

    某日
    小A打开手机,王者荣耀启动,连赢十把之后,辣鸡游戏真没意思,卸载。
    扭头看见没怎么翻过的Java从入门到放弃,心想自己写个小游戏岂不美哉?说着拿起键盘噼里啪啦一阵敲。

    `
    public class Main1 {

    public static void main(String[] args) {
    	// 用户选择英雄
    	String name = Main1.getPlayerInput();
    
                // 英雄放技能 
    	switch (name) {
    	case "亚瑟":
    		Arthur arthur = new Arthur();
    		arthur.skill1();
    		break;
    	case "露娜":
    		Luna luna = new Luna();
    		luna.skill1();
    		break;
    	case "孙尚香":
    		SunShangXiang xiang = new SunShangXiang();
    		xiang.skill1();
    		break;
    	}
    	
    }
    
    private static String getPlayerInput() {
    	System.out.println("请选择英雄:");
    	Scanner scanner = new Scanner(System.in);
    	String name = scanner.nextLine();
    	return name;
    }
    

    }
    `
    很自然的这么写,写了一连串他感觉这写的真是够啰嗦,如果英雄放大招岂不是又要逐个调用skill3()?三四个英雄还好,以后扩增到300个英雄……

    小A在键盘上飞舞的手停顿了一下,心想虽然我的手速够快,可是这么写下去手岂不是要断?
    突然想起昨天刚看的面向接口编程思想 …… o_★ 有了! 于是他写了个接口:

    `
    public interface SkillImpl {

    void skill1();
    void skill2();
    void skill3();
    

    }
    `
    并用Arthur实现了这个接口:

    `
    public class Arthur implements SkillImpl{

    public void skill1() {
    	System.out.println("【亚瑟】释放了1技能:誓约之盾");
    }
    public void skill2() {
    	System.out.println("【亚瑟】释放了2技能:回旋打击");
    }
    public void skill3() {
    	System.out.println("【亚瑟】释放了大招:圣剑裁决");
    }
    

    }
    `

    然后随手把main方法里的代码改了:

    `
    public class Main2 {

    public static void main(String[] args) throws Exception {
    	// 用户选择英雄
    	String name = Main2.getPlayerInput();
    	SkillImpl skillImpl;
    	switch (name) {
    	case "亚瑟":
    		skillImpl = new Arthur();
    		break;
    	case "露娜":
    		skillImpl = new Luna();
    		break;
    	case "孙尚香":
    		skillImpl = new SunShangXiang();
    		break;
    	default:
    		throw new Exception();
    	}
    	skillImpl.skill1();
    
    	
    }
    
    private static String getPlayerInput() {
    	System.out.println("请选择英雄:");
    	Scanner scanner = new Scanner(System.in);
    	String name = scanner.nextLine();
    	return name;
    }
    

    }
    `
    改完后小A看着自己的代码不自觉地点了点头,这样就把方法的调用统一起来了,全部集中在一个接口的方法调用上面。
    上一个版本的switch里除了有对象的生成还有业务逻辑,非常不单纯, 现在switch逻辑很简单,就只做一件事 ———— 给SkillImpl实例化。

    面向对象很多时候就是在做两件事:一是实例化对象,二是调用方法完成业务逻辑。现在调用方法完成业务逻辑已经OK了,
    但是单纯的 interface 可以统一方法的调用,却不能统一对象的实例化。
    如果又新增一个英雄还是要改业务主体的代码,并没有完全解决问题……

    小A陷入了沉思……如果把它提取成一个方法,再进行方法的调用,下一次就不用改main方法里的代码了。emm……可行。

    可是下次新增英雄还不是要改所调用的方法里的代码?!
    又一想需求是会变更的,代码中总是会存在不稳定,隔离这些不稳定,让主要逻辑方法里main 的代码是稳定的就可以了。
    想完,小A加了一个生产英雄的工厂类,把main方法里的代码挪了进去:

    `
    public class HeroFactory {

    public static SkillImpl getHero(String name) throws Exception {
    	SkillImpl skillImpl;
    	switch (name) {
    	case "亚瑟":
    		skillImpl = new Arthur();
    		break;
    	case "露娜":
    		skillImpl = new Luna();
    		break;
    	case "孙尚香":
    		skillImpl = new SunShangXiang();
    		break;
    	default:
    		throw new Exception();
    	}
    	return skillImpl;
    }
    

    }

    `
    现在main方法里看着清晰多了,我再放个技能,再来个大招,轻轻松松的:

    `
    public class Main3 {

    public static void main(String[] args) throws Exception {
    	// 用户选择英雄
    	String name = Main3.getPlayerInput();
    	SkillImpl skillImpl = HeroFactory.getHero(name);
    	skillImpl.skill1();
    	skillImpl.skill2();
    	skillImpl.skill3();
    
    	
    }
    
    private static String getPlayerInput() {
    	System.out.println("请选择英雄:");
    	Scanner scanner = new Scanner(System.in);
    	String name = scanner.nextLine();
    	return name;
    }
    

    }

    `

    小A不住点头,露出了欣慰的笑容,我的手算是保住了,果然以后还是要多看看书。

      > Java追求的是代码的稳定性和可维护性:
      > Java提倡面向抽象编程,而不要面向具体去编程。面向抽象编程表面上的目的是不要依赖一个具体的类,而是要去依赖抽象,它真正的目的是为了实现可维护的代码。
      > 对于生命周期比较长的项目,我们需要长期维护、迭代、更新,一些设计思想和方法论就非常非常重要。如果没有方法论在里面,以后需要更改某些属性,就可能引发非常严重的错误。
    

    面向接口编程思想:

     面向接口编程不与面向对象编程同级,而是附属于面向对象编程思想,是面向对象编程思想的精髓之一。这也是设计的一大原则:程序依赖接口,不依赖具体实现。
    

    一个接口就是我们要调用的一系列方法的集合,有对象将会响应这些方法调用。一个实现就是为接口存放代码和逻辑的地方。本质上讲,这个原则倡导的是,当我们写一个函数或一个方法时,我们应该引用相应的接口,而不是具体的实现类。这是一个非常强大的编程思想,我们写出越多可复用的代码,用于维护它们的时间就会越少,接口提供了非常优秀的抽象归纳,让我们的开发工作变得容易很多。虽然并不是什么时候都可以面向接口编程的,但遵循这种原则会让你更容易的写出可复用的更优雅的代码。【引用】链接:http://www.aqee.net/post/program-to-an-interface-fool.html

    定义

    在系统分析和架构中,分清层次和依赖关系,每个层次不是直接向其上层提供服务(即不是直接实例化在上层中),
    而是通过定义一组接口,仅向上层暴露其接口功能,上层对于下层仅仅是接口依赖,而不依赖具体类
    

    本质

    1.接口是一组规则的集合,它规定了实现本接口的类或者接口必须拥有的一组规则。
    2.接口是在一定粒度视图上同类事物的抽象表示,实现了多态性。
    

    优点

    1.结构清晰,使用方便。
    2.设计合理的接口,有利于程序的规范化,可并行进行开发,从而提高效率。
    3.提高系统的灵活性,当下层需要改变时,只要接口及接口功能不变,则上层不用做任何修改。
    4.实现了程序的可插拔性,对于不同的需求切换不同的实现,降低了耦合度,随着系统的复杂性的提高优势会愈加明显(低耦合、易扩展、易维护)。
    5.允许多重实现,弥补了继承的缺陷。
    

    缺点

    1.增加了设计复杂度,不适用于简单的系统。
    2.可能会降低代码的可复用性。
    3.可能会降低程序的执行效率。
    

    【引用】链接:https://www.cnblogs.com/aimaogoudexiaohao/p/12050928.html

      接口泛指实体把自己提供给外界的一种抽象化物,用以由内部操作分离出外部「沟通方法」,使其能被内部修改而不影响外界其他实体与其交互的方式。
    

    在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的,对系统设计人员来讲就不那么重要了(通俗的说,就是你会调接口就完事了,接口背后具体怎么实现的你不用管);而各个对象之间的协作关系(接口)则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程就是指按照这种思想来编程。(btw,所以那些设计接口的程序猿更赚钱啊,哦,应该喊他们架构师)。
    接口的作用 1. 制定标准 2. 提供可扩展性
    【引用】链接:https://zhuanlan.zhihu.com/p/119152601

    接口这个概念在实际生活中最常见的例子就是:插座!
    我们只需要事先定义好插座的接口标准,各大插座厂商只要按这个接口标准生产,管你什么牌子、内部什么电路结构,这些均和用户无关,用户拿来就可以用;而且即使插座坏了,只要换一个符合接口标准的新插座,一切照样工作!
    同理,实际代码设计也是这样!我们在设计一个软件的代码架构时,我们都希望事先约定好各个功能的接口(即:约定好接口签名和方法),实际开发时我们只需要实现这个接口就能完成具体的功能!后续即使项目变化、功能升级,程序员只需要按照接口约定重新实现一下,就可以达到系统升级和扩展的目的!
    【引用】链接:http://www.imooc.com/article/301555

  • 相关阅读:
    武汉科技大学ACM :1004: 零起点学算法74——Palindromes _easy version
    武汉科技大学ACM :1003: 零起点学算法14——三位数反转
    武汉科技大学ACM :1002: 零起点学算法38——求阶乘和
    武汉科技大学ACM :1001: 零起点学算法34——继续求多项式
    cos实现文件上传--推荐
    文件夹分级保存文件
    apache_fileupload实现文件上传_上传多个文件
    UEFI模式下安装Win 7系统
    武汉科技大学ACM :1008: A+B for Input-Output Practice (VIII)
    武汉科技大学ACM :1007: A+B for Input-Output Practice (VII)
  • 原文地址:https://www.cnblogs.com/hongcha/p/13121329.html
Copyright © 2011-2022 走看看