精华内容
下载资源
问答
  • java面向对象开发七大原则,阿里面试问到过,建议看看。简洁明了
  • java开发面向对象原则

    2012-03-20 15:30:11
    北大青鸟佳音旗舰教学内容在开发过程中用的一些原则
  • java开发六大基本原则

    万次阅读 多人点赞 2017-11-27 10:12:49
    设计模式之六大原则(转载)  关于设计模式的六大设计原则的资料网上很多,但是很多地方解释地都太过于笼统化,我也找了很多资料来看,发现CSDN上有几篇关于设计模式的六大原则讲述的比较通俗易懂,因此转载过来。 ...

    作者: 海子
        

    设计模式之六大原则(转载)

      关于设计模式的六大设计原则的资料网上很多,但是很多地方解释地都太过于笼统化,我也找了很多资料来看,发现CSDN上有几篇关于设计模式的六大原则讲述的比较通俗易懂,因此转载过来。

      原作者博客链接:http://blog.csdn.net/LoveLion/article/category/738450/7

    一.单一职责原则

      原文链接:http://blog.csdn.net/lovelion/article/details/7536542

      单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小。单一职责原则定义如下:

    单一职责原则(Single Responsibility Principle, SRP):一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。

          单一职责原则告诉我们:一个类不能太“累”!在软件系统中,一个类(大到模块,小到方法)承担的职责越多,它被复用的可能性就越小,而且一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作,因此要将这些职责进行分离,将不同的职责封装在不同的类中,即将不同的变化原因封装在不同的类中,如果多个职责总是同时发生改变则可将它们封装在同一类中。

          单一职责原则是实现高内聚、低耦合的指导方针,它是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,而发现类的多重职责需要设计人员具有较强的分析设计能力和相关实践经验。

          下面通过一个简单实例来进一步分析单一职责原则:

    Sunny软件公司开发人员针对某CRM(Customer Relationship  Management,客户关系管理)系统中客户信息图形统计模块提出了如图1所示初始设计方案:

    1  初始设计方案结构图

    在图1中,CustomerDataChart类中的方法说明如下:getConnection()方法用于连接数据库,findCustomers()用于查询所有的客户信息,createChart()用于创建图表,displayChart()用于显示图表。

    现使用单一职责原则对其进行重构。

          在图1中,CustomerDataChart类承担了太多的职责,既包含与数据库相关的方法,又包含与图表生成和显示相关的方法。如果在其他类中也需要连接数据库或者使用findCustomers()方法查询客户信息,则难以实现代码的重用。无论是修改数据库连接方式还是修改图表显示方式都需要修改该类,它不止一个引起它变化的原因,违背了单一职责原则。因此需要对该类进行拆分,使其满足单一职责原则,类CustomerDataChart可拆分为如下三个类:

          (1) DBUtil:负责连接数据库,包含数据库连接方法getConnection();

          (2) CustomerDAO:负责操作数据库中的Customer表,包含对Customer表的增删改查等方法,如findCustomers();

          (3) CustomerDataChart:负责图表的生成和显示,包含方法createChart()和displayChart()。

          使用单一职责原则重构后的结构如图2所示:

    2  重构后的结构图

    二.开闭原则

      原文链接:http://blog.csdn.net/lovelion/article/details/7537584

      开闭原则是面向对象的可复用设计的第一块基石,它是最重要的面向对象设计原则。开闭原则由Bertrand  Meyer1988年提出,其定义如下:

    开闭原则(Open-Closed Principle, OCP):一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。

          在开闭原则的定义中,软件实体可以指一个软件模块、一个由多个类组成的局部结构或一个独立的类

          任何软件都需要面临一个很重要的问题,即它们的需求会随时间的推移而发生变化。当软件系统需要面对新的需求时,我们应该尽量保证系统的设计框架是稳定的。如果一个软件设计符合开闭原则,那么可以非常方便地对系统进行扩展,而且在扩展时无须修改现有代码,使得软件系统在拥有适应性和灵活性的同时具备较好的稳定性和延续性。随着软件规模越来越大,软件寿命越来越长,软件维护成本越来越高,设计满足开闭原则的软件系统也变得越来越重要。

          为了满足开闭原则,需要对系统进行抽象化设计,抽象化是开闭原则的关键。在Java、C#等编程语言中,可以为系统定义一个相对稳定的抽象层,而将不同的实现行为移至具体的实现层中完成。在很多面向对象编程语言中都提供了接口、抽象类等机制,可以通过它们定义系统的抽象层,再通过具体类来进行扩展。如果需要修改系统的行为,无须对抽象层进行任何改动,只需要增加新的具体类来实现新的业务功能即可,实现在不修改已有代码的基础上扩展系统的功能,达到开闭原则的要求。

          Sunny软件公司开发的CRM系统可以显示各种类型的图表,如饼状图和柱状图等,为了支持多种图表显示方式,原始设计方案如图1所示:

    1 初始设计方案结构图

          在ChartDisplay类的display()方法中存在如下代码片段:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ......
    if  (type.equals( "pie" )) {
         PieChart chart =  new  PieChart();
         chart.display();
    }
    else  if  (type.equals( "bar" )) {
         BarChart chart =  new  BarChart();
         chart.display();
    }
    ......


          在该代码中,如果需要增加一个新的图表类,如折线图LineChart,则需要修改ChartDisplay类的display()方法的源代码,增加新的判断逻辑,违反了开闭原则。

          现对该系统进行重构,使之符合开闭原则。

           在本实例中,由于在ChartDisplay类的display()方法中针对每一个图表类编程,因此增加新的图表类不得不修改源代码。可以通过抽象化的方式对系统进行重构,使之增加新的图表类时无须修改源代码,满足开闭原则。具体做法如下:

          (1) 增加一个抽象图表类AbstractChart,将各种具体图表类作为其子类;

          (2)  ChartDisplay类针对抽象图表类进行编程,由客户端来决定使用哪种具体图表。

          重构后结构如图2所示:

    图2 重构后的结构图

          在图2中,我们引入了抽象图表类AbstractChart,且ChartDisplay针对抽象图表类进行编程,并通过setChart()方法由客户端来设置实例化的具体图表对象,在ChartDisplay的display()方法中调用chart对象的display()方法显示图表。如果需要增加一种新的图表,如折线图LineChart,只需要将LineChart也作为AbstractChart的子类,在客户端向ChartDisplay中注入一个LineChart对象即可,无须修改现有类库的源代码。    

           注意:因为xml和properties等格式的配置文件是纯文本文件,可以直接通过VI编辑器或记事本进行编辑,且无须编译,因此在软件开发中,一般不把对配置文件的修改认为是对系统源代码的修改。如果一个系统在扩展时只涉及到修改配置文件,而原有的Java代码或C#代码没有做任何修改,该系统即可认为是一个符合开闭原则的系统。

    三.里氏替换原则

      原文链接:http://blog.csdn.net/lovelion/article/details/7540445

      里氏代换原则由2008年图灵奖得主、美国第一位计算机科学女博士Barbara Liskov教授和卡内基·梅隆大学Jeannette Wing教授于1994年提出。其严格表述如下:如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1代换o2时,程序P的行为没有变化,那么类型S是类型T的子类型。这个定义比较拗口且难以理解,因此我们一般使用它的另一个通俗版定义:

    里氏代换原则(Liskov Substitution Principle, LSP):所有引用基类(父类)的地方必须能透明地使用其子类的对象。

          里氏代换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象。例如:我喜欢动物,那我一定喜欢狗,因为狗是动物的子类;但是我喜欢狗,不能据此断定我喜欢动物,因为我并不喜欢老鼠,虽然它也是动物。

          例如有两个类,一个类为BaseClass,另一个是SubClass类,并且SubClass类是BaseClass类的子类,那么一个方法如果可以接受一个BaseClass类型的基类对象base的话,如:method1(base),那么它必然可以接受一个BaseClass类型的子类对象sub,method1(sub)能够正常运行。反过来的代换不成立,如一个方法method2接受BaseClass类型的子类对象sub为参数:method2(sub),那么一般而言不可以有method2(base),除非是重载方法。

          里氏代换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象

          在使用里氏代换原则时需要注意如下几个问题:

          (1)子类的所有方法必须在父类中声明,或子类必须实现父类中声明的所有方法。根据里氏代换原则,为了保证系统的扩展性,在程序中通常使用父类来进行定义,如果一个方法只存在子类中,在父类中不提供相应的声明,则无法在以父类定义的对象中使用该方法。

          (2) 我们在运用里氏代换原则时,尽量把父类设计为抽象类或者接口,让子类继承父类或实现父接口,并实现在父类中声明的方法,运行时,子类实例替换父类实例,我们可以很方便地扩展系统的功能,同时无须修改原有子类的代码,增加新的功能可以通过增加一个新的子类来实现。里氏代换原则是开闭原则的具体实现手段之一。

          (3) Java语言中,在编译阶段,Java编译器会检查一个程序是否符合里氏代换原则,这是一个与实现无关的、纯语法意义上的检查,但Java编译器的检查是有局限的。

          在Sunny软件公司开发的CRM系统中,客户(Customer)可以分为VIP客户(VIPCustomer)和普通客户(CommonCustomer)两类,系统需要提供一个发送Email的功能,原始设计方案如图1所示:

    1原始结构图

          在对系统进行进一步分析后发现,无论是普通客户还是VIP客户,发送邮件的过程都是相同的,也就是说两个send()方法中的代码重复,而且在本系统中还将增加新类型的客户。为了让系统具有更好的扩展性,同时减少代码重复,使用里氏代换原则对其进行重构。

          在本实例中,可以考虑增加一个新的抽象客户类Customer,而将CommonCustomer和VIPCustomer类作为其子类,邮件发送类EmailSender类针对抽象客户类Customer编程,根据里氏代换原则,能够接受基类对象的地方必然能够接受子类对象,因此将EmailSender中的send()方法的参数类型改为Customer,如果需要增加新类型的客户,只需将其作为Customer类的子类即可。重构后的结构如图2所示:

    图2  重构后的结构图

          里氏代换原则是实现开闭原则的重要方式之一。在本实例中,在传递参数时使用基类对象,除此以外,在定义成员变量、定义局部变量、确定方法返回类型时都可使用里氏代换原则。针对基类编程,在程序运行时再确定具体子类。

      另外补充一篇关于里氏替换原则的一篇博文:

      http://blog.csdn.net/zhengzhb/article/details/7281833

    四.依赖倒置原则

      原文链接:http://blog.csdn.net/lovelion/article/details/7562783

      如果说开闭原则是面向对象设计的目标的话,那么依赖倒转原则就是面向对象设计的主要实现机制之一,它是系统抽象化的具体实现。依赖倒转原则是Robert C. Martin1996年为“C++Reporter”所写的专栏Engineering Notebook的第三篇,后来加入到他在2002年出版的经典著作“Agile Software Development, Principles, Patterns, and Practices”一书中。依赖倒转原则定义如下:

    依赖倒转原则(Dependency Inversion  Principle, DIP):抽象不应该依赖于细节,细节应当依赖于抽象。换言之,要针对接口编程,而不是针对实现编程。

          依赖倒转原则要求我们在程序代码中传递参数时或在关联关系中,尽量引用层次高的抽象层类,即使用接口和抽象类进行变量类型声明、参数类型声明、方法返回类型声明,以及数据类型的转换等,而不要用具体类来做这些事情。为了确保该原则的应用,一个具体类应当只实现接口或抽象类中声明过的方法,而不要给出多余的方法,否则将无法调用到在子类中增加的新方法。

          在引入抽象层后,系统将具有很好的灵活性,在程序中尽量使用抽象层进行编程,而将具体类写在配置文件中,这样一来,如果系统行为发生变化,只需要对抽象层进行扩展,并修改配置文件,而无须修改原有系统的源代码,在不修改的情况下来扩展系统的功能,满足开闭原则的要求。

          在实现依赖倒转原则时,我们需要针对抽象层编程,而将具体类的对象通过依赖注入(DependencyInjection, DI)的方式注入到其他对象中,依赖注入是指当一个对象要与其他对象发生依赖关系时,通过抽象来注入所依赖的对象。常用的注入方式有三种,分别是:构造注入,设值注入(Setter注入)和接口注入。构造注入是指通过构造函数来传入具体类的对象,设值注入是指通过Setter方法来传入具体类的对象,而接口注入是指通过在接口中声明的业务方法来传入具体类的对象。这些方法在定义时使用的是抽象类型,在运行时再传入具体类型的对象,由子类对象来覆盖父类对象。

          下面通过一个简单实例来加深对依赖倒转原则的理解:

          Sunny软件公司开发人员在开发某CRM系统时发现:该系统经常需要将存储在TXT或Excel文件中的客户信息转存到数据库中,因此需要进行数据格式转换。在客户数据操作类中将调用数据格式转换类的方法实现格式转换和数据库插入操作,初始设计方案结构如图1所示:

    1 初始设计方案结构图

          在编码实现图1所示结构时,Sunny软件公司开发人员发现该设计方案存在一个非常严重的问题,由于每次转换数据时数据来源不一定相同,因此需要更换数据转换类,如有时候需要将TXTDataConvertor改为ExcelDataConvertor,此时,需要修改CustomerDAO的源代码,而且在引入并使用新的数据转换类时也不得不修改CustomerDAO的源代码,系统扩展性较差,违反了开闭原则,现需要对该方案进行重构。

          在本实例中,由于CustomerDAO针对具体数据转换类编程,因此在增加新的数据转换类或者更换数据转换类时都不得不修改CustomerDAO的源代码。我们可以通过引入抽象数据转换类解决该问题,在引入抽象数据转换类DataConvertor之后,CustomerDAO针对抽象类DataConvertor编程,而将具体数据转换类名存储在配置文件中,符合依赖倒转原则。根据里氏代换原则,程序运行时,具体数据转换类对象将替换DataConvertor类型的对象,程序不会出现任何问题。更换具体数据转换类时无须修改源代码,只需要修改配置文件;如果需要增加新的具体数据转换类,只要将新增数据转换类作为DataConvertor的子类并修改配置文件即可,原有代码无须做任何修改,满足开闭原则。重构后的结构如图2所示:

    2重构后的结构图

        

          在上述重构过程中,我们使用了开闭原则、里氏代换原则和依赖倒转原则,在大多数情况下,这三个设计原则会同时出现,开闭原则是目标,里氏代换原则是基础,依赖倒转原则是手段,它们相辅相成,相互补充,目标一致,只是分析问题时所站角度不同而已。

    五.接口隔离原则

      原文链接:http://blog.csdn.net/lovelion/article/details/7562842

      接口隔离原则定义如下:

    接口隔离原则(Interface  Segregation Principle, ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。

          根据接口隔离原则,当一个接口太大时,我们需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。每一个接口应该承担一种相对独立的角色,不干不该干的事,该干的事都要干。这里的“接口”往往有两种不同的含义:一种是指一个类型所具有的方法特征的集合,仅仅是一种逻辑上的抽象;另外一种是指某种语言具体的“接口”定义,有严格的定义和结构,比如Java语言中的interface。对于这两种不同的含义,ISP的表达方式以及含义都有所不同:

          (1) 当把“接口”理解成一个类型所提供的所有方法特征的集合的时候,这就是一种逻辑上的概念,接口的划分将直接带来类型的划分。可以把接口理解成角色,一个接口只能代表一个角色,每个角色都有它特定的一个接口,此时,这个原则可以叫做角色隔离原则”。

          (2) 如果把“接口”理解成狭义的特定语言的接口,那么ISP表达的意思是指接口仅仅提供客户端需要的行为,客户端不需要的行为则隐藏起来,应当为客户端提供尽可能小的单独的接口,而不要提供大的总接口。在面向对象编程语言中,实现一个接口就需要实现该接口中定义的所有方法,因此大的总接口使用起来不一定很方便,为了使接口的职责单一,需要将大接口中的方法根据其职责不同分别放在不同的小接口中,以确保每个接口使用起来都较为方便,并都承担某一单一角色。接口应该尽量细化,同时接口中的方法应该尽量少,每个接口中只包含一个客户端(如子模块或业务逻辑类)所需的方法即可,这种机制也称为定制服务”,即为不同的客户端提供宽窄不同的接口。

          下面通过一个简单实例来加深对接口隔离原则的理解:

          Sunny软件公司开发人员针对某CRM系统的客户数据显示模块设计了如图1所示接口,其中方法dataRead()用于从文件中读取数据,方法transformToXML()用于将数据转换成XML格式,方法createChart()用于创建图表,方法displayChart()用于显示图表,方法createReport()用于创建文字报表,方法displayReport()用于显示文字报表。

    1 初始设计方案结构图

          在实际使用过程中发现该接口很不灵活,例如如果一个具体的数据显示类无须进行数据转换(源文件本身就是XML格式),但由于实现了该接口,将不得不实现其中声明的transformToXML()方法(至少需要提供一个空实现);如果需要创建和显示图表,除了需实现与图表相关的方法外,还需要实现创建和显示文字报表的方法,否则程序编译时将报错。

          现使用接口隔离原则对其进行重构。

          在图1中,由于在接口CustomerDataDisplay中定义了太多方法,即该接口承担了太多职责,一方面导致该接口的实现类很庞大,在不同的实现类中都不得不实现接口中定义的所有方法,灵活性较差,如果出现大量的空方法,将导致系统中产生大量的无用代码,影响代码质量;另一方面由于客户端针对大接口编程,将在一定程序上破坏程序的封装性,客户端看到了不应该看到的方法,没有为客户端定制接口。因此需要将该接口按照接口隔离原则和单一职责原则进行重构,将其中的一些方法封装在不同的小接口中,确保每一个接口使用起来都较为方便,并都承担某一单一角色,每个接口中只包含一个客户端(如模块或类)所需的方法即可。

          通过使用接口隔离原则,本实例重构后的结构如图2所示:

    2 重构后的结构图

         在使用接口隔离原则时,我们需要注意控制接口的粒度,接口不能太小,如果太小会导致系统中接口泛滥,不利于维护;接口也不能太大,太大的接口将违背接口隔离原则,灵活性较差,使用起来很不方便。一般而言,接口中仅包含为某一类用户定制的方法即可,不应该强迫客户依赖于那些它们不用的方法。

    六.迪米特法则

      原文链接:http://blog.csdn.net/lovelion/article/details/7563445

      迪米特法则来自于1987年美国东北大学(Northeastern University)一个名为“Demeter”的研究项目。迪米特法则又称为最少知识原则(LeastKnowledge Principle, LKP),其定义如下:

    迪米特法则(Law of  Demeter, LoD):一个软件实体应当尽可能少地与其他实体发生相互作用。

          如果一个系统符合迪米特法则,那么当其中某一个模块发生修改时,就会尽量少地影响其他模块,扩展会相对容易,这是对软件实体之间通信的限制,迪米特法则要求限制软件实体之间通信的宽度和深度。迪米特法则可降低系统的耦合度,使类与类之间保持松散的耦合关系。

          迪米特法则还有几种定义形式,包括不要和“陌生人”说话只与你的直接朋友通信等,在迪米特法则中,对于一个对象,其朋友包括以下几类:

          (1) 当前对象本身(this);

         (2) 以参数形式传入到当前对象方法中的对象;

          (3) 当前对象的成员对象;

          (4) 如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友;

          (5) 当前对象所创建的对象。

          任何一个对象,如果满足上面的条件之一,就是当前对象的“朋友”,否则就是“陌生人”。在应用迪米特法则时,一个对象只能与直接朋友发生交互,不要与“陌生人”发生直接交互,这样做可以降低系统的耦合度,一个对象的改变不会给太多其他对象带来影响。

          迪米特法则要求我们在设计系统时,应该尽量减少对象之间的交互,如果两个对象之间不必彼此直接通信,那么这两个对象就不应当发生任何直接的相互作用,如果其中的一个对象需要调用另一个对象的某一个方法的话,可以通过第三者转发这个调用。简言之,就是通过引入一个合理的第三者来降低现有对象之间的耦合度

          在将迪米特法则运用到系统设计中时,要注意下面的几点:在类的划分上,应当尽量创建松耦合的类,类之间的耦合度越低,就越有利于复用,一个处在松耦合中的类一旦被修改,不会对关联的类造成太大波及在类的结构设计上,每一个类都应当尽量降低其成员变量和成员函数的访问权限在类的设计上,只要有可能,一个类型应当设计成不变类在对其他类的引用上,一个对象对其他对象的引用应当降到最低

          下面通过一个简单实例来加深对迪米特法则的理解:

          Sunny软件公司所开发CRM系统包含很多业务操作窗口,在这些窗口中,某些界面控件之间存在复杂的交互关系,一个控件事件的触发将导致多个其他界面控件产生响应,例如,当一个按钮(Button)被单击时,对应的列表框(List)、组合框(ComboBox)、文本框(TextBox)、文本标签(Label)等都将发生改变,在初始设计方案中,界面控件之间的交互关系可简化为如图1所示结构:

    1 初始设计方案结构图

          在图1中,由于界面控件之间的交互关系复杂,导致在该窗口中增加新的界面控件时需要修改与之交互的其他控件的源代码,系统扩展性较差,也不便于增加和删除新控件。

          现使用迪米特对其进行重构。

          在本实例中,可以通过引入一个专门用于控制界面控件交互的中间类(Mediator)来降低界面控件之间的耦合度。引入中间类之后,界面控件之间不再发生直接引用,而是将请求先转发给中间类,再由中间类来完成对其他控件的调用。当需要增加或删除新的控件时,只需修改中间类即可,无须修改新增控件或已有控件的源代码,重构后结构如图2所示:

    2  重构后的结构图

    作者: 海子
             
    本博客中未标明转载的文章归作者 海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    展开全文
  • Java开发设计——七大原则

    千次阅读 多人点赞 2021-02-21 10:20:47
    一、开闭原则(Open Closed Principle,OCP) 含义 开闭原则的含义是:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。 作用 开闭原则是面向对象程序...

    一、开闭原则(Open Closed Principle,OCP)

    含义
    开闭原则的含义是:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。

    作用
    开闭原则是面向对象程序设计的终极目标,它使软件实体拥有一定的适应性和灵活性的同时具备稳定性和延续性。具体来说,其作用如下:

    ◆ 对软件测试的影响:软件遵守开闭原则的话,软件测试时只需要对扩展的代码进行测试就可以了,因为原有的测试代码仍然能够正常运行。

    ◆ 可以提高代码的可复用性:粒度越小,被复用的可能性就越大;在面向对象的程序设计中,根据原子和抽象编程可以提高代码的可复用性。

    ◆ 可以提高软件的可维护性:遵守开闭原则的软件,其稳定性高和延续性强,从而易于扩展和维护。

    实现方式
    可以通过“抽象约束、封装变化”来实现开闭原则,即通过接口或者抽象类为软件实体定义一个相对稳定的抽象层,而将相同的可变因素封装在相同的具体实现类中。

    因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节可以从抽象派生来的实现类来进行扩展,当软件需要发生变化时,只需要根据需求重新派生一个实现类来扩展就可以了。

    二、里氏替换原则(Liskov Substitution Principle,LSP)

    含义
    继承必须确保超类所拥有的性质在子类中仍然成立。

    里氏替换原则主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中蕴含的原理。里氏替换原是继承复用的基础,它反映了基类与子类之间的关系,是对开闭原则的补充,是对实现抽象化的具体步骤的规范。

    作用
    ◆ 里氏替换原则是实现开闭原则的重要方式之一。

    ◆ 它克服了继承中重写父类造成的可复用性变差的缺点。

    ◆ 它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。

    实现方式
    里氏替换原则通俗来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。也就是说:子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法。

    如果通过重写父类的方法来完成新的功能,这样写起来虽然简单,但是整个继承体系的可复用性会比较差,特别是运用多态比较频繁时,程序运行出错的概率会非常大。

    如果程序违背了里氏替换原则,则继承类的对象在基类出现的地方会出现运行错误。这时其修正方法是:取消原来的继承关系,重新设计它们之间的关系。

    三、依赖倒置原则(Dependence Inversion Principle,DIP)

    含义
    依赖倒置原则的原始定义为:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。其核心思想是:要面向接口编程,不要面向实现编程。

    依赖倒置原则是实现开闭原则的重要途径之一,它降低了客户与实现模块之间的耦合。

    作用
    ◆ 依赖倒置原则可以降低类间的耦合性。

    ◆ 依赖倒置原则可以提高系统的稳定性。

    ◆ 依赖倒置原则可以减少并行开发引起的风险。

    ◆ 依赖倒置原则可以提高代码的可读性和可维护性。

    实现方式
    依赖倒置原则的目的是通过要面向接口的编程来降低类间的耦合性,所以我们在实际编程中只要遵循以下4点,就能在项目中满足这个规则:

    ◆ 每个类尽量提供接口或抽象类,或者两者都具备。

    ◆ 变量的声明类型尽量是接口或者是抽象类。

    ◆ 任何类都不应该从具体类派生。

    ◆ 使用继承时尽量遵循里氏替换原则。

    四、单一职责原则(Single Responsibility Principle,SRP)

    含义
    单一职责原则规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分。

    优点
    单一职责原则的核心就是控制类的粒度大小、将对象解耦、提高其内聚性。如果遵循单一职责原则将有以下优点:

    ◆ 降低类的复杂度。一个类只负责一项职责,其逻辑肯定要比负责多项职责简单得多。

    ◆ 提高类的可读性。复杂性降低,自然其可读性会提高。

    ◆ 提高系统的可维护性。可读性提高,那自然更容易维护了。

    ◆ 变更引起的风险降低。变更是必然的,如果单一职责原则遵守得好,当修改一个功能时,可以显著降低对其他功能的影响。

    实现方式
    单一职责原则是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,再封装到不同的类或模块中,而发现类的多重职责需要设计人员具有较强的分析设计能力和相关重构经验。

    五、接口隔离原则(Interface Segregation Principle,ISP)

    含义
    以上两个定义的含义是:要为各个类建立它们需要的专用接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。

    优点
    接口隔离原则是为了约束接口、降低类对接口的依赖性,遵循接口隔离原则有以下5个优点:

    ◆ 将臃肿庞大的接口分解为多个粒度小的接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。

    ◆ 接口隔离提高了系统的内聚性,减少了对外交互,降低了系统的耦合性。

    ◆ 如果接口的粒度大小定义合理,能够保证系统的稳定性;但是,如果定义过小,则会造成接口数量过多,使设计复杂化;如果定义太大,灵活性降低,无法提供定制服务,给整体项目带来无法预料的风险。

    ◆ 使用多个专门的接口还能够体现对象的层次,因为可以通过接口的继承,实现对总接口的定义。

    ◆ 能减少项目工程中的代码冗余。过大的大接口里面通常放置许多不用的方法,当实现这个接口的时候,被迫设计冗余的代码。

    实现方式
    在具体应用接口隔离原则时,应该根据以下几个规则来衡量:

    ◆ 接口尽量小,但是要有限度。一个接口只服务于一个子模块或业务逻辑。

    ◆ 为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法。

    ◆ 了解环境,拒绝盲从。每个项目或产品都有选定的环境因素,环境不同,接口拆分的标准就不同深入了解业务逻辑。

    ◆ 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。

    六、迪米特法则(Law of Demeter,LoD)

    含义
    迪米特法则的定义是:只与你的直接朋友交谈,不跟“陌生人”说话。其含义是:如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。

    迪米特法则中的“朋友”是指:当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等,这些对象同当前对象存在关联、聚合或组合关系,可以直接访问这些对象的方法。

    优点
    迪米特法则要求限制软件实体之间通信的宽度和深度,正确使用迪米特法则将有以下两个优点:

    ◆ 降低了类之间的耦合度,提高了模块的相对独立性。

    ◆ 由于亲合度降低,从而提高了类的可复用率和系统的扩展性。

    但是,过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低。所以,在釆用迪米特法则时需要反复权衡,确保高内聚和低耦合的同时,保证系统的结构清晰。

    实现方式
    从迪米特法则的定义和特点可知,它强调以下2点:

    ◆ 从依赖者的角度来说,只依赖应该依赖的对象。

    ◆ 从被依赖者的角度说,只暴露应该暴露的方法。

    所以,在运用迪米特法则时要注意以下6点:

    ◆ 在类的划分上,应该创建弱耦合的类。类与类之间的耦合越弱,就越有利于实现可复用的目标。

    ◆ 在类的结构设计上,尽量降低类成员的访问权限。

    ◆ 在类的设计上,优先考虑将一个类设置成不变类。

    ◆ 在对其他类的引用上,将引用其他对象的次数降到最低。

    ◆ 不暴露类的属性成员,而应该提供相应的访问器(set方法和get 方法)。

    ◆ 谨慎使用序列化(Serializable)功能。

    七、合成复用原则(Composite Reuse Principle,CRP)

    含义
    它要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。

    作用
    通常类的复用分为继承复用和合成复用两种,继承复用虽然有简单和易实现的优点,但它也存在以下缺点:

    ◆ 继承复用破坏了类的封装性。因为继承会将父类的实现细节暴露给子类,父类对子类是透明的,所以这种复用又称为“白箱”复用。

    ◆ 子类与父类的耦合度高。父类的实现的任何改变都会导致子类的实现发生变化,这不利于类的扩展与维护。

    ◆ 它限制了复用的灵活性。从父类继承而来的实现是静态的,在编译时已经定义,所以在运行时不可能发生变化。

    采用组合或聚合复用时,可以将已有对象纳入新对象中,使之成为新对象的一部分,新对象可以调用已有对象的功能,它有以下优点:

    ◆ 它维持了类的封装性。因为成分对象的内部细节是新对象看不见的,所以这种复用又称为“黑箱”复用。

    ◆ 新旧类之间的耦合度低。这种复用所需的依赖较少,新对象存取成分对象的唯一方法是通过成分对象的接口。

    ◆ 复用的灵活性高。这种复用可以在运行时动态进行,新对象可以动态地引用与成分对象类型相同的对象。

    实现方式
    合成复用原则是通过将已有的对象纳入新对象中,作为新对象的成员对象来实现的,新对象可以调用已有对象的功能,从而达到复用。

    总结

    这7种设计原则是软件设计模式必须尽量遵循的原则,各种原则要求的侧重点不同:

    ◆ 开闭原则是总纲,它告诉我们要对扩展开放,对修改关闭。

    ◆ 里氏替换原则告诉我们不要破坏继承体系。

    ◆ 依赖倒置原则告诉我们要面向接口编程。

    ◆ 单一职责原则告诉我们实现类要职责单一。

    ◆ 接口隔离原则告诉我们在设计接口的时候要精简单一。

    ◆ 迪米特法则告诉我们要降低耦合度。

    ◆ 合成复用原则告诉我们要优先使用组合或者聚合关系复用,少用继承关系复用。

    2021年最新Java面试题(带答案)

    展开全文
  • Java9模块化开发核心原则与实践
  • java开发设计六大基本原则

    千次阅读 2017-03-25 18:41:23
    1.遵循单一职责原则 一个类只专注于做一件事; 高内聚,低耦合;2.开放-封闭原则 对拓展开放,对修改关闭(尽可能不动原有代码进行拓展); 高内聚,低耦合; 为达到目的,需对系统进行抽象化设计(关键); ...

    1.遵循单一职责原则


    一个类只专注于做一件事;
    高内聚,低耦合;

    2.开放-封闭原则


    对拓展开放,对修改关闭(尽可能不动原有代码进行拓展);
    高内聚,低耦合;
    为达到目的,需对系统进行抽象化设计(关键);
    UML举例:
    这里写图片描述

    3.里氏代换原则(LSP)


    子类必须能够替换它们的基类型,基类与子类可互换,客户端没有察觉情况下;
    低耦合;
    很容易实现同一父类下的各个子类的互换,而客户端可以毫不察觉;

    UML实例:
    这里写图片描述

    士兵只能使用WeaponGun,而无法使用ToyGun杀敌,如果使用ToyGun将会出错。这就是里氏替换原则。

    4.依赖倒置原则


    这个是开闭原则的基础,具体内容:面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。

    5.接口隔离原则(Interface Segregation Principle)


    使用多个专一功能的接口比使用一个总接口总要好,但不能过渡;
    一个接口不能过于臃肿;
    高内聚
    会使一个软件系统功能拓展时,修改的压力不会影响到别的对象那去;
    UML实例:
    这里写图片描述

    Model只要满足好身材这个条件,就有可能成为模特,漂亮女孩满足好身材和好。AngelaBaby即有好身材又好。

    6.迪米特法则(Law of Demeter)


    又叫最少知识原则;
    对象与对象之间应该使用尽可能少的方法来关联,避免千丝万缕的关系;
    低耦合;
    类知道其他类应尽量少;
    类可以访问其他类的方法或者属性也应尽量少;

    这里写图片描述

    如果Lily和Jack自己做hamburg那么就会与Vegetable、Meat、Bread产生千丝万缕关系。上图,则由KFC来做,这样Lily和Jack就只与Hamburg有关关联,与材料就没有关联了。

    展开全文
  • Java 9 模块化开发:核心原则与实践

    万次阅读 2018-12-21 23:30:20
    Java 9 向 Java 平台引入了模块系统,这是一个非常重要的飞跃,标志着模块化 Java 软件开发的新纪元。当需要创建灵活且易于维护的代码时,模块化是一个关键的架构设计原则。本书给出了 Java 模块系统的明确概述,并...

    内容简介

    Java 9 向 Java 平台引入了模块系统,这是一个非常重要的飞跃,标志着模块化 Java 软件开发的新纪元。当需要创建灵活且易于维护的代码时,模块化是一个关键的架构设计原则。本书给出了 Java 模块系统的明确概述,并演示了如何通过创建模块化应用程序来帮助管理以及降低复杂性。

    作者引导我们了解了模块系统中的相关概念以及工具,介绍了可以将现有代码迁移到模块中的模式并以模块的方式构建新的应用程序。

    本书特色:

    • 了解 Java 平台自身如何实现模块化;
    • 学习模块化如何影响应用程序的设计、编译、打包以及开发;
    • 编写自己的模块;
    • 使用模式改进任意代码库的可维护性、灵活性以及重用性;
    • 学习如何使用服务来创建解耦模块;
    • 将现有代码迁移到模块,并学习如何使用并不是模块的现有库;
    • 创建优化的自定义运行时映像,从而改变装载模块化 Java 应用程序的方式。

    作者简介

    桑德 · 马克(Sander Mak),荷兰 Luminis 公司的一名研究员,开发了许多主要用于 JVM 上的模块化以及可扩展软件,但也会在需要的地方使用 TypeScript。他经常在各种会议上发言,并热衷于通过博客(http://branchandbound.net)和作为 Pluralsight 平台的讲师分享知识。

    保罗 · 巴克(Paul Bakker) Netflix 公司的一名高级软件工程师,在其 Edge Developer Experience 团队主要从事工具的开发,以提高公司内部开发人员的工作效率。曾与他人合作编著了 Modular Cloud Apps with OSGi(由O''Reilly 出版公司出版)一书。Paul 经常在与模块化、容器技术相关主题的会议上发言。

    本书内容

    译者序

    JDK 9是 Java 开发工具包的第9个主要版本,于2017年7月下旬发布,它带来了许多令人兴奋的新功能。Java 9定义了一套全新的模块系统。当代码库越来越大,创建盘根错节的“意大利面条式代码”的概率呈指数级增长,这时候就得面对两个基础问题。首先,很难真正地对代码进行封装,而系统对不同部分(也就是 JAR 文件)之间的依赖关系并没有明确的概念。每一个公共类都可以被类路径之下任何其他公共类所访问,这样就会导致无意中使用了并不想被公开访问的 API。其次,类路径本身也存在问题:你怎么知晓所有需要的 JAR 都已经有了,或者是不是会有重复的项呢?模块系统把这两个问题都解决了。

    模块化的 JAR 文件都包含一个额外的模块描述符。在这个模块描述符中,对其他模块的依赖是通过 requires 来表示的。另外,exports 语句控制着哪些包是可以被其他模块访问的。所有不被导出的包默认都封装在模块里。

    本书共分为三部分,第一部分包括6章。第1章主要介绍了什么是模块化以及 Java 9模块的主要特点。第2章学习了如何定义模块,以及使用哪些概念管理模块之间的交互。第3章在第2章的基础上通过构建自己的模块进一步学习相关模块概念。第4章讨论了可以解耦模块的服务。第5章和第6章探讨了模块化模式,以及如何以最大限度地提高可维护性和可扩展性的方式使用模块。

    第二部分包括4章。第7章和第8章重点介绍了如何将现有的代码迁移到模块中。第9章通过迁移案例详细讨论了如何实现迁移。如果你是一名库的创建者或者维护者,那么第10章将对你有所帮助,其介绍了如何向库添加模块支持。

    第三部分也包括4章,主要介绍了一些模块化开发工具。第11章学习了主要的 IDE 以及构建工具。第12章介绍了如何对模块进行测试。第13章和第14章主要介绍了自定义运行时映像以及对模块化未来的展望。

    本书图文并茂、技术新、实用性强,以大量的实例对 Java 9模块系统做了详细的解释,是学习 Java 9的读者不可缺少的实用参考书籍。本书可作为 Java 编程人员的参考手册,适合计算机技术人员使用。此外,书中还提供了相关参考资料,如果在阅读过程中遇到不明白的方法或属性,可以参阅相关内容。

    参与本书翻译的人有王净、田洪、范园芳、范桢、胡训强、晏峰、余佳隽、张洁、何远燕、任方燕。最终由王净负责统稿。在此,要感谢我们的家人,他们总是无怨无悔地支持我们的一切工作。

    在翻译过程中,我们尽量保持原书的特色,并对书中出现的术语和难词难句进行了仔细推敲和研究。但毕竟有少量技术是译者在自己的研究领域中不曾遇到过的,所以疏漏和争议之处在所难免,望广大读者提出宝贵意见。

    最后,希望广大读者能多花些时间细细品味这本凝聚作者和译者大量心血的书籍,为将来的职业生涯奠定良好的基础。

    王净

    2018年3月于广州

    什么是 Java 中的模块化?对于一些人来说,模块化是一个开发原则,即对接口进行编程并隐藏实现的细节,这就是所谓的封装学派(school of encapsulation)。对于另外一些人来说,模块化是指依赖类加载器来提供动态执行环境,这就是所谓的隔离学派(school of isolation)。还有一些人认为模块化指的是工件、存储库以及相关工具,这就是所谓的配置学派(school of configuration)。虽然单独来看,这些观点都是正确的,但它们都太片面,感觉更像是一个不太清晰的“大故事”的几个片段。如果开发人员知道其部分代码仅供内部使用,那么他们为什么不能像隐藏类或字段一样容易地隐藏包呢?如果代码只能在依赖项存在的情况下编译和运行,那么这些依赖项为什么不能顺畅地从编译过程流向打包过程,再到安装过程,最后到执行过程呢?如果工具只有在提供了原始自描述工件时才能起作用,那么如何重用那些只是普通 JAR 文件的旧版本库呢?

    Java 9将模块作为 Java 平台的高级功能,从而很自然地引入了模块化概念。模块是一组用于重用的包,这个简单的概念对代码开发、部署以及运行的方式产生了非常深刻的影响。一旦将包放置到模块中,Java 中用来促进和控制“重用”的长期存在的机制(接口、访问控制、JAR 文件、类加载器以及动态链接)就能更好地工作。

    首先,模块以其他机制无法实现的方式阐明了程序的结构。许多开发人员会惊讶地发现他们的代码结构并没有想象得那么好。例如,由多个 JAR 文件组成的代码库可以实现不同 JAR 文件中类之间的循环,但在不同模块中的类之间的循环却是禁止的。实现代码库模块化的动机之一是一旦实现了模块化,就可以避免出现因为循环依赖所产生的“泥球”(ball of mud)[1]。此外,使用模块进行开发还可以实现通过服务进行编程,从而减少耦合并进一步提高抽象性。

    其次,模块产生了其他机制无法实现的代码责任感。从模块中导出包的开发人员实际上对 API 的稳定性做出了承诺,甚至模块本身的名称也是 API 的一部分。如果开发人员将太多的功能捆绑到单个模块中,那么就会导致该模块牵扯到大量与任何单一任务无关的依赖项;任何重用该模块的人都会意识到其杂乱无序的性质,即使模块的内部是隐藏的。使用模块进行开发可以促使每个开发人员思考其代码的稳定性和内聚性。

    大多数人对桌布戏法都非常熟悉,即将桌布从桌子上迅速拿走,同时不能打翻盘子和杯子。对于那些使用 Java 9的人来说,设计一个可以嵌入 Java 虚拟机(Java 虚拟机由自20世纪90年代以来所开发的数以百万计的类所控制)的模块系统感觉就像是反向表演桌布戏法。事实证明,模块化 JDK 导致了戏法的失败,因为一些知名的库为了自身的发展而不愿意将模块系统应用于 JDK 模块所带来的封装。Java 9设计中的这种矛盾很难在学术上得到解决。最终,来自社区的长期反馈促使模块系统为开发人员提供了各种各样的“杠杆”和“调节盘”,使得模块化平台代码可以享受真正强大的封装,而模块化应用程序代码可以享受“足够强大”的封装。随着时间的推移,我们认为在模块化 JDK 方面进行的大胆选择将会使得代码更加可靠。

    只有当一个模块系统适用于所有人时,该系统才是最好的。今天创建模块的开发人员越多,明天就会有更多的开发人员创建模块。但是那些尚未创建自己模块的开发人员又该怎么办呢?毫不夸张地说,Java 9会像关注模块内的代码一样关注模块外的代码。代码库的作者是唯一应该对代码库进行模块化的开发人员,在完成模块化之前,模块系统必须为模块中的代码提供一种方法来“接触”模块之外的代码,而这也导致了自动模块的设计,本书将会详细介绍这部分内容。

    Sander 和 Paul 都是 Java 方面的专家,同时也是 Java 9生态系统可信任的指导者。他们身处 Java 9开发的最前沿,是迁移流行开源库的先驱。本书面向那些对 Java 中模块化的核心原则和最佳实践感兴趣的人的,包括希望创建可维护组件的应用程序开发人员,寻求关于迁移和反射建议的库开发人员,以及希望利用模块系统高级功能的框架开发人员。我希望本书可以帮助你创建出程序结构经得起时间考验的 Java 程序。

    Alex Buckley

    Oracle Java 平台组

    圣克拉拉,2017年7月


    [1] 泥球是指一个随意化的杂乱的结构化系统,只是代码的堆砌和拼凑,往往会导致很多错误或者缺陷。—译者注

    前言

    Java 9向 Java 平台引入了模块系统,这是一个重大的飞跃,标志着 Java 平台上模块化软件开发的一个新时代的开始。看到这些变化让人感到非常兴奋,希望读者看完本书后也会感到兴奋。在深入了解模块系统之前需要做好充分利用该系统的准备。

    本书读者

    本书为那些想要提高应用程序的设计和结构的 Java 开发者而编写。Java 模块系统改进了设计和构建 Java 应用程序的方法。即使你不打算马上使用模块,了解 JDK 模块化本身也是非常重要的一步。在熟悉了本书第一部分所介绍的模块之后,希望你也能真正理解后续关于迁移的相关章节。

    将现有代码移至 Java 9和模块系统将成为一项越来越常见的任务。

    本书绝不是对 Java 的一般性介绍。我们假设你拥有在一个团队中编写过较大 Java 应用程序的经验,在较大的 Java 应用程序中模块变得越来越重要。作为一名经验丰富的 Java 开发人员,应该认识到类路径所带来的问题,从而有助于理解模块系统及其功能。

    除了模块系统之外,Java 9中还有许多其他变化。然而,本书主要关注模块系统及其相关功能。当然,在适当的情况下,在模块系统的上下文中也会讨论其他 Java 9功能。

    编写本书的原因

    很多读者从 Java 早期开始就是 Java 用户,当时 Applet 还非常流行。多年来,我们使用和喜欢过许多其他平台和语言,但 Java 仍然是主要工具。在构建可维护的软件方面,模块化是一个关键原则。多年来人们花费了大量精力来构建模块化软件,并逐渐热衷于开发模块化应用程序。曾经广泛使用诸如 OSGi 之类的技术来实现模块化,但 Java 平台本身并不支持这些技术。此外,还可通过 Java 之外的其他工具学习模块化,比如 JavaScript 的模块系统。当 Java 9推出了期待已久的模块系统时,我们认为并不能只是使用该功能,还应该帮助其刚入职的开发人员了解模块系统。

    也许在过去10年的某个时候你曾经听说过 Jigsaw 项目。经过多年的发展,Jigsaw 项目具备了 Java 模块系统许多功能的原型。Java 的模块系统发展断断续续。Java 7和 Java 8最初计划包含 Jigsaw 项目的发展结果。

    随着 Java 9的出现,长期的模块化尝试最终完成了正式模块系统的实现。多年来,各种模块系统原型的范围和功能发生了许多变化。即使你一直在密切关注该过程,也很难弄清楚最终 Java 9模块系统真正包含什么。本书将会给出模块系统的明确概述,更重要的是将介绍模块系统能够为应用程序的设计和架构做些什么。

    本书内容

    本书共分为三个部分:

    1)Java 模块系统介绍。

    2)迁移。

    3)模块化开发工具。

    第一部分主要介绍如何使用模块系统。首先从介绍模块化 JDK 本身开始,然后学习创建自己的模块,随后讨论可以解耦模块的服务,最后探讨模块化模式以及如何以最大限度地提高可维护性和可扩展性的方式使用模块。

    第二部分主要介绍迁移。有可能读者现在所拥有的 Java 代码不是使用专为模块系统而设计的 Java 库。该部分介绍如何将现有代码迁移到模块中,以及如何使用尚未模块化的现有库。如果你是一名库的编写者或者维护者,那么这部分中有一章专门介绍了如何向库添加模块支持。

    第三部分(也是最后一部分)主要介绍工具。该部分介绍了 IDE 的现状以及构建工具。此外还会学习如何测试模块,因为模块给(单元)测试带来了一些新的挑战,也带来了机会。最后学习链接(linking)——模块系统另一个引人注目的功能。

    虽然建议从头到尾按顺序阅读本书,但是请记住并不是所有的读者都必须这样阅读。建议至少详细阅读前四章,从而具备基本知识,以便更好地阅读本书的其他章节。如果时间有限并且有现有的代码需要迁移,那么可以在阅读完前四章后跳到本书的第二部分。一旦完成了迁移,就可以回到“更高级”的章节。

    使用代码示例

    本书包含了许多代码示例。所有代码示例都可以在 GitHub(https://github.com/java9-modularity/examples)上找到。在该存储库中,代码示例是按照章节组织的。在本书中,使用下面的方法引用具体的代码示例:chapter3/helloworld,其含义是可以在“https://github.com/java9-modularity/examples/chapter3/helloworld”中找到示例。

    强烈建议在阅读本书时使用相关的代码,因为在代码编辑器中可以更好地阅读较长的代码段。此外还建议亲自动手改写代码,如重现书中所讨论的错误。动手实践胜过读书。

    排版约定

    下面列出的是书中所使用的字体约定:

    斜体(Italic)

    表示新术语、URL、电子邮件地址、文件名以及文件扩展名。

    等宽字体(Constant width)

    用于程序清单,以及在段落中引用程序元素,如变量或函数名称、数据库、数据类型、环境变量、语句和关键字。

    等宽粗体(Constant width bold)

    显示应由用户逐字输入的命令或其他文本。

    等宽斜体(Constant width italic)

    显示应该由用户提供的值或由上下文确定的值所替换的文本。

    Safari 在线电子书

    Safari(前身为 Safari Books Online)是一个基于会员制的为企业、政府、教育工作者和个人提供培训和参考的平台。

    会员可以访问来自250家出版商的书籍、培训视频、学习路径、交互式教程和精心策划的播放列表,包括 O'Reilly Media、Harvard Business Review、Prentice Hall Professional、Addison-Wesley Professional、Microsoft Press、Sams、Que、Peachpit Press、Adobe、Focal Press、Cisco Press、John Wiley&Sons、Syngress、Morgan Kaufmann、IBM Redbooks、Packt、AdobePress、FT Press、Apress、Manning、New Riders、McGraw-Hill、Jones&Bartlett,以及Course Technology,等等。

    更多信息,请访问 http://oreilly.com/safari

    如何联系我们

    对于本书,如果有任何意见或疑问,请按照以下地址联系本书出版商。

    美国:

    O'Reilly Media,Inc.

    1005Gravenstein Highway North

    Sebastopol,CA 95472

    中国:

    北京市西城区西直门南大街2号成铭大厦 C 座807室(100035)

    奥莱利技术咨询(北京)有限公司

    要询问技术问题或对本书提出建议,请发送电子邮件至:

    bookquestions@oreilly.com

    要获得更多关于我们的书籍、会议、资源中心和 O’Reilly 网络的信息,请参见我们的网站:

    http://www.oreilly.com

    http://www.oreilly.com.cn

    我们在 Facebook 上的主页:
    http://facebook.com/oreilly

    我们在 Twitter 上的主页:
    http://twitter.com/oreillymedia

    我们在 YouTube 上的主页:
    http://www.youtube.com/oreillymedia

    致谢

    编写本书的想法来源于2015年在 JavaOne 会议上与来自 O’Reilly 的 Brian Foster 的一次谈话,非常感谢你委托我们参与这个项目。从那时起,很多人对本书的编写提供了帮助。

    感谢 Alex Buckley、Alan Bateman 和 Simon Maple 所给出的重要技术评论和对本书所提出的许多改进意见。此外,还要感谢 O’Reilly 的编辑团队,Nan Barber 和 Heather Scherer 考虑到了所有的组织细节。

    如果没有妻子 Suzanne 的坚定支持,编写本书是不可能的。多少个夜晚和周末,我都无法陪伴妻子和三个孩子。感谢你一直陪我到最后!此外,还要感谢 Luminis(http://luminis.eu/)为编写本书所提供的支持。我很高兴能成为公司的一员,我们的口号是“知识是共享的唯一财富”。

    Sander Mak

    我也要感谢妻子 Qiushi,在我编写这第二本书籍时始终支持我,即使在我们搬到世界的另一个位置的时候。此外,还要感谢 Netflix(http://netflix.com/)和 Luminis(http://luminis.eu/),感谢它们给予我编写本书的时间和机会。

    Paul Bakker

    本书第1章、第7章、第13章和第14章的漫画由 Oliver Widder(http://geek-and-poke.com/)创建,并获得 Creative Commons Attribution 3.0Unported(CC BY 3.0)(http://creativecommons.org/licenses/by/3.0/deed.en_US)的许可。本书的作者将漫画改为横向和灰色。

    第1章 模块化概述
    第2章 模块和模块化 JDK
    第3章 使用模块
    第4章 服务
    第5章 模块化模式(一)
    第5章 模块化模式(二)
    第6章 高级模块化模式
    第7章 没有模块的迁移
    第8章 迁移到模块
    第9章 迁移案例研究:Spring 和 Hibernate
    第10章 库迁移
    第11章 构建工具和 IDE
    第12章 测试模块
    第13章 使用自定义运行时映像进行缩减
    第14章 模块化的未来

    阅读全文: http://gitbook.cn/gitchat/geekbook/5c189a881e59245d4d2aac4f

    展开全文
  • java SOLID原则

    千次阅读 2017-01-09 10:41:10
    众所周知,Java编程最基本的原则就是要追求高内聚和低耦合的解决方案和代码模块设计,S.O.L.I.D是面向对象设计和编程(OOD&OOP)中几个重要编码原则(Programming Priciple)的首字母缩写。 SRP The ...
  • 敏捷软件开发原则、模式与实践 薪水支付案例研究 java代码实现
  • Java开发手册以 Java 开发者为中心视角,划分为编程规约、异常日志、单元测试、安全规约、MySQL 数据库、工程结构、设计规约七个维度进行Java开发规范; Java安全编码规范明确安全编码的基本原则,常见漏洞对应的...
  • 白话阿里巴巴Java开发手册高级篇

    万次阅读 多人点赞 2019-11-08 16:25:22
    不久前,阿里巴巴发布了《阿里巴巴Java开发手册》,总结了阿里巴巴内部实际项目开发过程中开发人员应该遵守的研发流程规范,这些流程规范在一定程度上能够保证最终的项目交付质量,通过在时间中总结模式,并推广给...
  • Java9模块化开发核心原则与实践》_王净等译
  • JAVA原则之依赖倒置原则

    千次阅读 2016-03-24 15:23:07
    JAVA原则之依赖倒置原则本博客大部分内容来自于网络,写下来方便以后查阅1.什么是依赖倒置原则 简单来说 A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。 B.抽象不应该依赖于具体实现,具体...
  • 阿里巴巴Java开发手册快速学习

    万次阅读 2017-04-14 09:04:38
    善医者“未有形而除之”,提高工程健壮性最好的...《阿里巴巴Java开发手册》是阿里巴巴的内部编码规范,阿里官方的Java代码规范标准,这份开发手册不仅规范了一些开发细节,也提出了很多工程开发的哲学,值得好好阅读。
  • java开发的代码规范

    千次阅读 2017-03-22 09:26:25
    java开发代码规范及部分注意事项
  • Java全栈开发

    万次阅读 多人点赞 2019-05-02 16:02:05
    Java全栈开发 ------------目录------------ github搜索 技术网站 方志朋的博客 面试经验 javaSE 多线程 框架介绍 springboot JavaEE框架 分布式框架 大型网站分布式架构(一套) 全栈解决方案(完整) ...
  • 这是经典,能找到说明你了解经典 敏捷软件开发原则、模式与实践
  • 详细描述了Java代码的编写规范,适用于企业级Java开发
  • Java开闭原则

    千次阅读 2013-10-24 10:45:42
    Java开闭原则
  • 阿里JAVA开发手册零度的思考理解(一)

    千次阅读 多人点赞 2017-10-27 07:53:21
    缘由阿里JAVA开发手册已经发表有很长时间了,值得认真研究思考推广 阿里官方的Java代码规范标准,这份开发手册不仅规范了一些开发细节,也提出了很多工程开发的哲学,值得好好阅读。 可谓包罗万象,几乎日常Java...
  • JAVA软件开发

    千次阅读 2017-09-30 14:25:17
    Java方向:JAVA初级程序员、JAVA计算程序员、 JAVA工程师、J2EE系统工程师等。 .Net方向: .Net程序员网站开发工程师 .Net工程师等。 其它方向:简单的管理信息系统开发和维护人员、网页制作和客户端脚本程序...
  • Java作为目前最流行的开发语言之一,固然具有一个完善的异常处理机制。本文将对异常处理机制来一次大的总结,后面会讲解一些原则性问题、开发技巧以及经常遇到的异常。文章结构:1.异常机制树的讲解; 2.异常处理...
  • JAVA开发出现的BUG集

    千次阅读 2018-09-30 00:14:05
    Java开发中所遇到的所有BUG进行汇总
  • 硬肝4.4w字为你写成Java开发手册

    万次阅读 多人点赞 2020-05-09 09:29:28
    Java 是 Sun Microsystems 于1995 年首次发布的一种编程语言和计算平台。编程语言还比较好理解,那么什么是 计算平台 呢? 计算平台是在电脑中运行应用程序(软件)的环境,包括硬件环境和软件环境。一般系统平台...
  • 请问,如果我有一个团队需要完成一个比较有规模的JAVA网站开发项目,如何搭建AGILE原则开发环境比较好呢?请说地详细一点。谢谢!
  • [PDF高清]敏捷软件开发原则、模式与实践(Java版)中文版.rar [PDF高清]敏捷软件开发原则、模式与实践(Java版)中文版.rar
  • java JNI开发

    千次阅读 2013-07-02 12:38:12
    Jni程序开发的一般操作步骤如下: l 编写java中的调用类 l 用javah生成c/c++原生函数的头文件 l c/c++中调用需要的其他函数功能,实现原生函数(原则上可以调用任何资源) l 将项目依赖的所有原生库和资源加入...
  • 每次阿里新出Java开发手册,都会抽时间读一读。不仅如此,还会将最新的Idea插件更新一番,以规范开发。这个习惯养成很久了,以至于将Idea更新到最新版本时,发现阿里对应的插件还不能用,竟然有些懊恼升级了。 以铜...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 234,610
精华内容 93,844
关键字:

java开发原则

java 订阅