软件工程基本概念

软件工程三要素:

方法:完成软件开发的各项任务的技术方法,为软件开发提供 “如何做” 的技术
工具:为运用方法而提供的自动的或半自动的软件工程的支撑环境
过程:为了获得高质量的软件所需要完成的一系列任务的框架,它规定了完成各项任务的工作步骤,如何将软件工程方法与软件工具相结合,合理、及时地进行软件开发
 
软件生命周期:
  可行性分析阶段 
  需求分析阶段 
  系统设计阶段
  系统实现阶段
  测试阶段
  维护阶段
 
软件开发过程:
软件开发过程是在软件生命周期的软件系统开发过程中,一系列活动和软件生成结果的集合。软件过程模型描述软件开发过程的各项活动、角色、产品及其相互关系的模型。
目前有若干软件过程模型,各种模型有其不同的特点,并适用于不同的开发方法。例如,瀑布模型、循环模型、螺旋模型、增量模型和喷泉模型等。

不同的软件开发方法和软件开发模型要求有不同的工程体系。

 
统一建模语言UML
统一建模语言UML(Unified Modeling Language)是专门用来进行软件系统设计和架构建模的一门可视化建模语言,它通过各种图示展示了软件系统的方方面面。
 
UML图有很多种,对于程序员来说,最频繁使用的莫过于类图。类图主要是用来显示系统中的类、接口以及它们之间的静态结构和关系的一种静态模型。类图中最基本的元素是类、接口。软件设计师设计出类图后,程序员就可以用代码实现类图中包含的内容。
在UML类图中描述具体类
 
 
 
第一行表示:类名
第二行表示:属性
第三行表示:方法
- 表示:private
+表示:public
#表示:protected
 
在UML类图中描述抽象类
在第一行会出现《abstract》
在UML类图中描述接口
在第一行会出现《interface》
 
使用类图表示关系
类和类、类和接口、接口和接口之间存在一定关系,共有六种类型:分别是实现关系、泛化关系Generalization(继承关系)、关联关系、依赖关系、聚合关系、组合关系
 
泛化关系(Generalization)是指对象与对象之间的继承关系。
关联关系(Association)是指对象和对象之间的连接,它使一个对象知道另一个对象的属性和方法。在Java中,关联关系的代码表现形式为一个对象含有另一个对象的引用。关联关系有单向关联和双向关联
依赖 (Dependency) 关系是一种弱关联关系。依赖关系在Java中的具体代码表现形式为B为A的构造器或方法中的局部变量、方法或构造器的参数、方法的返回值,或者A调用B的静态方法。
聚合(Aggregation)是关联关系的一种特例,它体现的是整体与部分的拥有关系,即“has a”的关系。此时整体与部分之间是可分离的,它们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享,所以聚合关系也常称为共享关系。 
组合(Composition)也是关联关系的一种特例,它同样体现整体与部分间的包含关系,即“contains a”的关系。但此时整体与部分是不可分的,部分也不能给其它整体共享,作为整体的对象负责部分的对象的生命周期。这种关系比聚合更强,也称为强聚合。 
 
面向对象系统分析与设计
在面向对象技术中,建造整个软件系统的过程常常被称为面向对象的分析和设计(Object-Oriented Analysis and Design,OOAD)。对于我们要开发的软件系统来说,OOAD解决了系统是什么(面向对象的系统分析,即OOA)以及如何做的问题(面向对象的系统设计,即OOD),OOP只是用编程语言去实现该系统。 
 
 
 
 
内聚度:
定义:表示一个应用程序的单个单元所负责的任务数量和多样性。内聚与单个类或者单个方法单元相关。
耦合度:
耦合度表示类之间关系的紧密程度。
设计原则
一)单一职责
Single Responsibility Principle,SRP
定义:所有的对象都应该有单一的职责,它提供的所有的服务也都仅围绕着这个职责。
二)开闭原则   开闭原则是面向对象设计的核心所在
开闭原则(Open-Close Principle,简称OCP)是指一个软件实体(类、模块、方法等)应该对扩展开放,对修改关闭。
遵循开闭原则设计出来的模块具有两个基本特征:
对于扩展是开放的(Open for extension):模块的行为可以扩展,当应用的需求改变时,可以对模块进行扩展,以满足新的需求。
对于更改是封闭的(Closed for modification):对模块行为扩展时,不必改动模块的源代码或二进制代码。
三)里氏替换原则
里氏替换原则(The Liskov Substitution Principle,LSP)
定义:在一个软件系统中,子类应该能够完全替换任何父类能够出现的地方,并且经过替换后,不会让调用父类的客户程序从行为上有任何改变。里氏替换原则常用来检查两个类是否为继承关系。
最典型的例子:

正方形不是长方形
鸵鸟不是鸟
四)依赖倒转原则
依赖倒转原则(Dependency Inversion Principle,简称DIP)是指将两个模块之间的依赖关系倒置为依赖抽象类或接口。
具体有两层含义:
高层模块(调用类)不应该依赖于低层模块(被调用的类),二者都应该依赖于抽象;
抽象不应该依赖于细节,细节应该依赖于抽象。
要针对接口编程,不要针对实现编程
五)组合/聚合复用原则
组合/聚合复用原则(Composite/Aggregation Reuse Principle,CARP)
定义:是指要尽量使用组合/聚合而非继承来达到复用目的。另一种解释是在一个新的对象中使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象委托功能达到复用这些对象的目的。 

 六)接口隔离原则

接口隔离原则(Interface Segregation Principle,ISP)
定义:是指客户不应该依赖它们用不到的方法,只给每个客户它所需要的接口。换句话说,就是不能强迫用户去依赖那些他们不使用的接口。
接口的设计原则:接口的设计应该遵循最小接口原则,不要把用户不使用的方法塞进同一个接口里。
接口的继承原则:如果一个接口A继承另一个接口B,则接口A相当于继承了接口B的方法,那么继承了接口B后的接口A也应该遵循上述原则:不应该包含用户不使用的方法。
七)迪米特法则
迪米特法则(Law of Demeter,LOD),又称为“最少知识原则”,
定义:一个软件实体应当尽可能少的与其他实体发生相互作用。
最典型的例子:不要和陌生人说话。
 
创建型设计模式 
模式描述的是具有代表性的重复性问题及其解答方案. 
为什么要学习设计模式:
1) 促进复用,提高系统的重用性
2) 提高系统的可维护性
3) 增加表达能力: 设计模式有很强的语言表述性
4)帮助我们更好的进行软件设计
 
模式分类:
架构模式:架构是指一个软件系统整体的组织结构。架构模式描述软件系统的组织结构的一些规则和指南。通过这些规则和指南,我们可以把预定义的、职责明确的子系统有效地组织起来。
设计模式:设计模式描述的是在软件系统的某一局部不断重现的核心解决方案,这种解决方案以完善的设计结构出现,可以被应用到以后出现的类似的环境中。和架构模式相比,设计模式关注的是更为微观的问题。
 
设计模式的分类
基础设计模式(Gof23种设计模式): 不与特定域,平台或编程语言关联
1)创建模式: 涉及对象的创建 

工厂方法模式(Factory Method); 抽象工厂模式(Abstract Factory);创建者模式(Builder);原型模式(Prototype);单例模式(Singleton)。

2)结构模式:涉及类和对象的组合

外观模式(Facade);适配器模式(Adapter);代理模式(Proxy);装饰模式(Decorator);桥模式(Bridge);组合模式(Composite);享元模式(Flyweight)。

3)行为模式: 刻画了类和对象交换及分配职责的方式.主要目标是解耦
 
 模板方法模式(Template Method);观察者模式(Observer);状态模式(State);策略模式(Strategy);职责链模式(Chain of Responsibility);命令模式(Command);访问者模式(Visitor);调停者模式(Mediator);备忘录模式(Memento);迭代器模式(Iterator);解释器模式(Interpreter)。
 
 
单例模式(Singleton)
主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。 
使用单例模式(1)
 public class Singleton {
  private Singleton(){}
  //在自己内部定义自己一个实例,注意这是private
//预加载
  private static Singleton instance = new Singleton();
  
//这里提供了一个供外部访问本class的静态方法,
//可以直接访问    
public static Singleton getInstance() {   
 return instance;    
  }
}

使用单例模式(2)

 public class Singleton {
private Singleton (){}
//延迟加载
  private static Singleton instance = null; 
public static synchronized Singleton getInstance() {  
//这个方法比上面有所改进,不用每次都进行生成
//对象,只是第一次使用时生成实例,提高了效率! 
 if (instance==null)   
 instance=new Singleton();  
return instance;   
}
}
//这种方式在多线程的情况下,由于每次获取实例的时候都要对//getInstance()方法加锁,获取锁才能运行,效率会受影响。

使用单例模式(3)

 //双锁机制:
public class Singleton {
private Singleton (){}
  private static Singleton instance = null; 
public static Singleton getInstance(){ 
 if (instance==null)
synchronized(Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
return instance;  
  }
}
//这种方式只是在初始化Singleton那部分代码的时候添加同步锁,这样提高了//效率。

 原型模式(Prototype)

定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节 。
 原型模式浅度克隆:
克隆的对象的对象的属性的基本数据类型,浅度克隆的对象需要实现Cloneable。
       /**
* 浅克隆
* @return
* @throws CloneNotSupportedException
*/
public Player qianClone() throws CloneNotSupportedException{
return (Player) super.clone();
}
原型模式深度克隆:
可以克隆对象的引用数据类型,深度克隆主要应用的的是序列化机制,实现Serializable。
       /**
* 深克隆
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public Player deepClone() throws IOException, ClassNotFoundException{
ByteArrayOutputStream bos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(this); ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bis);
Player p=(Player) ois.readObject();
return p; }

 

创建者模式(Builder)

Builder模式是把创建复杂对象的过程和部件的创建分别开来,分别用Builder类和Director类来表示,从而达到解耦的目的
注意: Builder模式强调的是有相同建造顺序的过程,而具体建造细节不同。创建的复杂对象的内部构建间的建造顺序通常是稳定的,但是对象内部的构建通常面临着复杂的变化.
 
 结构型设计模式用于处理类或对象之间的组合,即描述类和对象之间怎样组织起来形成大的结构,从而实现新的功能。
 
 外观(Facade)模式
为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
 
装饰器(Decorator)模式
 装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象添加功能。通常给对象添加功能,要么直接修改对象添加相应的功能,要么派生对应的子类来扩展,抑或是使用对象组合的方式。显然,直接修改对应的类这种方式并不可取。在面向对象的设计中,而我们也应该尽量使用对象组合,而不是对象继承来扩展和复用功能。装饰器模式就是基于对象组合的方式,可以很灵活的给对象添加所需要的功能。装饰器模式的本质就是动态组合。动态是手段,组合才是目的。总之,装饰模式是通过把复杂的功能简单化,分散化,然后再运行期间,根据需要来动态组合的这样一个模式。
 
代理(Proxy)模式
对其他对象提供一种代理以控制对这个对象的访问
 
 桥梁(Bridge)模式
将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化"
 
适配器(Adaptor)模式
把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口原因不匹配而无法一起工作的两个类能够一起工作。
 
模板方法模式(Template Method)

定义一个算法的骨架,而将一些实现步骤延迟到子类中。把不变的行为搬到超类,去除子类中重复的代码来体现他的优势。

策略(Strategy )模式

在业务当中常常出现一个问题有一组算法,在不同的情况下我们有可能使用不同的算法。我们需要找到一种灵活简便的设计方式:将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。
 
观察者模式(Observer)
在软件系统中,我们有时需要定义一种一对多的依赖关系. 让多个观察者对象同时监听某一个主题对象, 这个主题对象在状态发生变化的时候,会通知所有的观察者对象,使他们能够自动更新自己。
 
三层架构模式
三层架构模式下,用户界面放在表现层上,业务逻辑放在业务层上,数据访问放在数据访问层(或持久层)上,采用这种方式可以将复杂的业务逻辑从用户界面代码中抽取出来,单独放到中间层,用对象加以建模和组织。
 
 
 
 
 

MVC模式

模型(Model)用于封装数据,代表了某应用程序的核心功能,负责处理用户的数据,实现业务逻辑。同时,模型还为视图的显示提供数据,并可被多个视图所共享。
视图(View)用于显示数据、收集数据和用户打交道,主要指与用户交互的界面,即应用程序的外观。它只负责将数据转交给控制器;同时还负责展示模型传递给用户的数据,当后台模型更新数据时,视图也应随之更新。
控制器(Controller)用于改变数据以及模型的状态,负责接收用户的请求和数据,然后做出判断将请求和数据交到哪一个模型来处理,最后调用视图来显示模型返回的数据。
 
DAO模式
 

DAO 模式有两个主要作用:

1、抽象数据源

2、抽象相关的 CRUD 逻辑(增删改查)

 
 示例代码 前面的单独模式里有!
 

OOAD理论知识小结的更多相关文章

  1. 【HTTP缓存】浏览器缓存理论知识

    时间:2016-12-12 17:51:30 作者: zhongxia 零.前言 这里主要写的是理论,具体实践的比较少,后期写一个实践教程,内容基本都是从参考文章里面抄过来的[看完文章,顺便写做下笔记 ...

  2. js中函数的一些理论知识

      函数的一些理论知识 1. 函数:                执行一个明确的动作并提供一个返回值的独立代码块.同时函数也是javascript中的一级公民(就是函数和其它变量一样). 2.函数的 ...

  3. Android app开发知识小结

    Android知识小结 这是一个知识的总结,所以没有详解的讲解. 一.分辨率Android中dp长度.sp字体使用.px像素.in英寸.pt英寸1/72.mm毫米 了解dp首先要知道density,d ...

  4. 用VC进行COM编程所必须掌握的理论知识

    一.为什么要用COM 软件工程发展到今天,从一开始的结构化编程,到面向对象编程,再到现在的COM编程,目标只有一个,就是希望软件能象积方块一样是累起来的,是组装起来的,而不是一点点编出来的.结构化编程 ...

  5. 图形学理论知识 BRDF 双向反射分布函数(Bidirectional Reflectance Distribution Function)

    图形学理论知识 BRDF 双向反射分布函数 Bidirectional Reflectance Distribution Function BRDF理论 BRDF表示的是双向反射分布函数(Bidire ...

  6. TestNG学习-001-基础理论知识

    此 文主要讲述用 TestNG 的基础理论知识,TestNG 的特定,编写测试过程三步骤,与 JUnit4+ 的差异,以此使亲对 TestNG 测试框架能够有一个简单的认知. 希望能对初学 TestN ...

  7. C/C++ 位域知识小结

    C/C++ 位域知识小结 几篇较全面的位域相关的文章: http://www.uplook.cn/blog/9/93362/ C/C++位域(Bit-fields)之我见 C中的位域与大小端问题 内存 ...

  8. [转] DDD领域驱动设计(三) 之 理论知识收集汇总

    最近一直在学习领域驱动设计(DDD)的理论知识,从网上搜集了一些个人认为比较有价值的东西,贴出来和大家分享一下: 我一直觉得不要盲目相信权威,比如不能一谈起领域驱动设计,就一定认为国外的那个Eric ...

  9. Winsock网络编程笔记(4)----基本的理论知识

    前面的笔记记录了Winsock的入门编程,领略了Winsock编程的乐趣..但这并不能算是掌握了Winsock,加深理论知识的理解才会让后续学习更加得心应手..因此,这篇笔记将记录一些有关Winsoc ...

随机推荐

  1. Java读取修改Properties文件

    properties文件是我们经常需要操作一种文件,它使用一种键值对的形式来保存属性集. 无论在学习上还是工作上经常需要读取,修改,删除properties文件里面的属性. 本文通过操作一个prope ...

  2. Trie树的数组实现原理

    Trie(Retrieval Tree)又称前缀树,可以用来保存多个字符串,并且非常便于查找.在trie中查找一个字符串的时间只取决于组成该串的字符数,与树的节点数无关.因此,它的查找速度通常比二叉搜 ...

  3. PHP后台图片上传作品 接口

    //把新图片添加到文件夹里 public function info($file=''){ $info = $file->validate(['ext'=>'jpg'])->rule ...

  4. HDU 2476 区间DP-刷字符问题-思维考察

    区间DP-刷字符问题-思维考察 翻译了一下这个题,一看还是有点难以入手,标明了是区间DP问题,但是如何DP呢 来捋一捋思路吧 dp[i][j]肯定是从i刷到j所要的次数但是它的i和j是s1串还是s2串 ...

  5. html 语法

    p: 源代码中包含多行,但是浏览器会忽略多行 <br />产生折行效果 h1:居中用样式实现 :水平线,有的很像border-top/bottom,或许用 实现更好 pre: 预格式化的文 ...

  6. 定时任务 Wpf.Quartz.Demo.4

    本文继续介绍定时任务 Wpf.Quartz.Demo.3的一些小细节, 代码也请前往第3节下载. 1.RichTextBox右键菜单 <RichTextBox.ContextMenu>   ...

  7. ssh连接卡在【To escape to local shell, press 'Ctrl+Alt+]'.】的解决方法

    一.现象 1.使用xshell连接远程主机的时候一直卡在To escape to local shell, press 'Ctrl+Alt+]'.,要等很久才能连上: Connecting to 19 ...

  8. Android在onCreate中获取控件的宽高

    在某些需求下,我们需要在onCreate的时候就获取到控件的宽高,但是如果直接用view.getWidth()或view.getHeight()会得到0.这是因为在onCreate执行的时候,控件还没 ...

  9. oracle 11g RAC数据库监听配置相关

    oracle RAC 监听配置基本和单实例的配置相同 11g之后 安装RAC的过程中,不需要执行netca来手动创建监听,在安装集群软件的时候,会自动创建监听程序: 而在DBCA建库的时候,又会自动创 ...

  10. Cookies与session的区别

    Cookies 机制 Cookies是服务器在本地机器上存储的一段文本,并随每一个请求发送至同一个服务器. IETF RFC2965 HTTP State Management Mechanism 是 ...