OOAD
什么是OOAD?
面向对象的分析与设计,使用面向对象的思想对一个系统的分析与设计
UML:
什么是UML?
统一的建模语言,什么是建模?将客观事物图形化,比如盖楼房,首先要把地基打好
统一指的是什么?在计算机领域有很多的图形语言,这样就需要一个标准,UML就是这样的一个标准,建模就是将需求用图的方式表达出来
UML的组成:
1. 元素:角色,用例
2. 图形
3. 扩展机制:扩展基本元素功能的机制
图形分类:
静态图,动态图
静态图:类图(描述类与类之间关系的图),对象图,部署图(拓扑结构),组件图,用例图(从客户的角度来描述系统的整个功能)
动态图:协作图(按空间的交互图),序列图(时序图,描述多个对象按时间的交互过程),活动图(描述业务流程,也能做一个操作的建模),状态图(描述单个的对象,或者是单个的子系统的状态变化)
类图:
类图,描述类与类之间关系的图
例子:图书管理系统
1. 利用OO的思想找对象:如:图书管理员,借书人,库存管理人员,书籍等等
2. 把他们抽象出来:找到与业务有关系的对象和对象的属性
3. 形成类,画出类图来
4. 实例并建立实例间的通讯
类之间的关系:
1. 继承
2. 实现
3. 关联
4. 依赖
5. 聚合
6. 组合
什么是关联?类的属性使用的是另一个类的引用或者是对象
什么是依赖?除了属性,其他地方使用了另一个类的对象,引用,属性,方法就叫A类依赖B类
/**
* 知识点:
* 关联
* 程序目标:
* java文件说明:
* A.java
* B.java
* Test.java:
* 让A和B关联起来,让A类调用B类的方法,让B类使用A类的方法
*/
package MY.module01.leitu.guanlian;
public class Test {
public static void test(){
A a=new A();
B b=new B();
a.setB(b);
b.setA(a);
a.getB().bf();
b.getA().af();
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Test.test();
}
}
package MY.module01.leitu.guanlian;
public class A {
private B b;
public A() {
super();
// TODO Auto-generated constructor stub
}
public A(B b) {
super();
// TODO Auto-generated constructor stub
this.b = b;
}
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
public void af(){
System.out.println("A‘s af()");
}
}
package MY.module01.leitu.guanlian;
public class B {
private A a;
public B() {
super();
// TODO Auto-generated constructor stub
}
public B(A a) {
super();
// TODO Auto-generated constructor stub
this.a = a;
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
public void bf(){
System.out.println("B‘s bf()");
}
}
/**
* 知识点:
* 依赖的三种情况
* 程序目标:
* java文件:
* A.java
* B.java
* 一个类的方法去使用另一个类的元素
*/
package MY.module01.leitu.yilai;
public class A {
public void a1(B b){
int rst=b.add(1,2);
System.out.println(rst);
}
public void a2(){
B b=new B();
int rst=b.add(1,2);
System.out.println(rst);
}
public void a3(){
int rst=B.add2(10,20);
System.out.println(rst);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
A a=new A();
a.a1(new B());
a.a2();
a.a3();
}
}
package MY.module01.leitu.yilai;
public class B {
public int add(int i,int j){
return i+j;
}
public static int add2(int i,int j){
return i+j;
}
}
什么是聚合?
比如说同学聚会,有很多的同学聚集在一起,但是,缺少几个也没有什么关系
什么是组合?
比如说人,有心脏,肝,肺,组成为一个人,如果少了其中的一部分,就会死掉,谁也离不开谁
静态图:用例图
从客户的角度来描述系统的整个过程
组成:
角色,用例,关联
角色之间的关系:
继承关系,依赖关系
例如:客户是一个角色,客户分为大客户,小客户,这是继承关系
借书人和图书管理员就是依赖关系
用例的关系:包含,扩展关系
例如:借书功能:登陆,查询等,这个是包含
静态图:部署图
整个系统的软硬件拓扑结构
如:CPU,eclipes等
静态图:组件图
表示物理的实现,实现指的是代码,这个用的少
动态图:序列图
按时间的先后顺序描述对象之间的交互
/**
* 知识点:
* 模拟序列图的执行
* 程序目标:
* java文件:
* Client.java:调用MainController类的方法
* MainController.java:这个方法中调用了Service类的方法
* Service.java:这个类的方法调用了另一个类的方法
* DAO.java:这个类的方法调用自身的一个方法,这叫反身消息
*/
package MY.module01.leitu.xulietu;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MainController m=new MainController();
m.f();
}
}
package MY.module01.leitu.xulietu;
public class MainController {
public void f(){
Service s=new Service();
s.f();
}
}
package MY.module01.leitu.xulietu;
public class Service {
public void f(){
DAO d=new DAO();
d.genName();
}
}
package MY.module01.leitu.xulietu;
public class DAO {
public void genName(){
System.out.println("hello");
f();
}
private void f(){
System.out.println("dao‘s shi fan shen");
}
}
动态图:活动图
可以有分之的判断
动态图:状态图
可以看到对象的状态变化
设计模式:
为什么要设计?
1. 软件的复用
2. 软件的维护
开闭原则:
对高层的修改关闭,对低层的扩展开放
模板方法:它实现了开闭原则
/**
* 知识点:
* 开-闭原则:模板方法
* 程序目标:
* java文件:
* CET6.java:高层的逻辑,只开发了给低层用的方法,听,说
* ConcretCET6.java:这里来实现听,说
* TestCET6.java
*/
package MY.module01.sjms.kbyz;
public class TestCET6 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
CET6 c=new ConcretCET6();
c.passCET6();
}
}
package MY.module01.sjms.kbyz;
public abstract class CET6 {
//高层业务逻辑
public final void passCET6(){
listen();
say();
}
//提供给低层实现的业务
abstract protected void listen();
abstract protected void say();
}
package MY.module01.sjms.kbyz;
public class ConcretCET6 extends CET6{
@Override
protected void listen() {
// TODO Auto-generated method stub
System.out.println("listen");
}
@Override
protected void say() {
// TODO Auto-generated method stub
System.out.println("say");
}
}
里氏代换原则:
任何父类适用的地方,子类一定适用,子类可以当父类用
策略模式:实现了里氏代换原则,解决了可选算法的问题
什么是策略模式?针对共同的问题,提供解决方案或指导原则或好坏结果
/**
* 知识点:
* 里氏代换原则:策略模式
* 程序目标:
* 打折的例子,涉及到可选算法的问题
* java文件:
* Context.java:打折的方法和设置折扣的方法,和DisCount为关联关系
* 这里体现了里氏代换原则,子类当父类用
* DisCount.java:打折算法抽象类
* dis1.java:打折算法1
* dis2.java:打折算法2
* Client.java:1.设置折扣率,2.打折
*/
package MY.module01.sjms.celuemoshi;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Context c=new Context();//算法选择器
// c.setD(new dis2());
c.setD(new dis1());//选择折扣
c.getprice(100);//打折
}
}
package MY.module01.sjms.celuemoshi;
public class Context {
private DisCount d;
public void setD(DisCount d) {
this.d = d;
}
public void getprice(double price){
System.out.println(d.discout(price));
}
}
package MY.module01.sjms.celuemoshi;
public class dis1 extends DisCount{
@Override
public double discout(double price) {
// TODO Auto-generated method stub
return price*0.8;
}
}
package MY.module01.sjms.celuemoshi;
public class dis2 extends DisCount{
@Override
public double discout(double price) {
// TODO Auto-generated method stub
return price;
}
}
package MY.module01.sjms.celuemoshi;
public abstract class DisCount {
public abstract double discout(double price);
}
依赖倒转原则:
什么是依赖倒转原则?要依赖抽象,不要依赖具体实现
这句话是什么意思呢?抽象指的是什么?具体实现指的又是什么?谁要依赖抽象?
一个程序要按照高层的设计思路来实现具体的程序功能,抽象就是高层,具体实现就是为了完成高层的一个目标而写的程序代码,高层就是战略,低层是战术,高层是整体目标,低层是目标的实现,高层是思想,低层是行为
什么是倒转?这个名字的含义是什么?
以往的过程式编程注重的是具体的功能实现方法,也就是低层,它决定了高层,这样是不合理的,所以要将这个错误的方式扭转过来,取名叫依赖倒转原则
三种依赖(耦合)关系的种类:
零耦合:不可能
具体耦合:具体的类和类之间的联系
抽象耦合:高层抽象类与类之间的联系
如何实现依赖倒转原则呢?
三种模式:
第一,工厂方法模式
第二,模板方法模式
第三,迭代子模式
接口隔离原则:
使用多个专门的接口要比使用一个总的接口要好
比如:人类(接口) 学生(具体类) 老师(具体类) 学生老师类(具体类):这个类要想拥有学生和老师的方法就很麻烦了,所以,需要再添加两个接口,学生接口和老师接口
组合聚合复用原则:CARP
将其他对象的功能融合到新的对象里,如果其中一个对象死掉了,另一个对象也不能用了,那么这种情况叫组合,反之,叫聚合
/**
* 知识点:
* 依赖关系,组合聚合复用,里氏代换原则结合这是聚合
* 程序目标:
* 例子:人学习技能
* People.java:人 具体类
* Actor.java:技能类接口
* Student.java:技能类具体类 学习方法
* Teacher.java:技能类具体类 教书方法
* Test.java:让人具备学习和教书的方法,并使用这些能力
*/
package MY.module01.sjms.CARP.t1;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Actor a=new Student();
Actor b=new Teacher();
People p=new People();
p.studyJineng(a);
p.studyJineng(b);
p.useJineng();
}
}
package MY.module01.sjms.CARP.t1;
public interface Actor {
void jineng();
}
package MY.module01.sjms.CARP.t1;
public class Teacher implements Actor{
public void jineng() {
// TODO Auto-generated method stub
System.out.println("theach....");
}
}
package MY.module01.sjms.CARP.t1;
public class Student implements Actor{
public void jineng() {
// TODO Auto-generated method stub
System.out.println("study..");
}
}
package MY.module01.sjms.CARP.t1;
import java.util.ArrayList;
import java.util.List;
public class People {
private String name;
private int age;
private List<Actor>list;
public People(){
list=new ArrayList<Actor>();
}
public void studyJineng(Actor a){
list.add(a);
}
public void useJineng(){
for(Actor a:list){
a.jineng();
}
}
}
迪米特法则(LoD):
最少知识原则:
1. 尽量减少耦合:类与类之间的访问减少,利用的资源少些
2. 对远程对象的访问最好用粗粒度接口来实现
3. 不要和陌生人说话,只和直接认识的人联系就好了
什么是远程对象?什么是粗粒度接口?
这个远程对象系统外的对象 ,如果有一个朋友圈和一些陌生人,陌生人就属于系统外的对象,就是远程对象,其中有一个人是这个朋友圈的同时也认识这些陌生人,那么如果朋友圈中的其他人想与陌生人联系,需要通过他来实现,这个他就是门面对象 ,这个对象需要通过一个接口来实现,而且这个接口设计的要和这个对象合适
/*
* 知识点:
* 迪米特法则(最少知识原则):门面模式
* 程序目标:
* Computer.java:看成远程对象
* Lamp.java:看成远程对象
* Office.java:看成远程对象
* People.java:人,看成朋友圈
* WorkOffFacade.java:门面对象
*/
package MY.module01.sjms.Lod.t1;
public class People {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
WorkOffFacade w=new WorkOffFacade();
w.closeWorkOff();
}
}
package MY.module01.sjms.Lod.t1;
//门面对象
public class WorkOffFacade {
public void closeWorkOff(){
new Computer().closeComputer();
new Lamp().closeLamp();
new Office().closeOther();
}
}
package MY.module01.sjms.Lod.t1;
public class Computer {
public void closeComputer(){
System.out.println("closeComputer");
}
}
package MY.module01.sjms.Lod.t1;
public class Lamp {
public void closeLamp(){
System.out.println("closeLamp");
}
}
package MY.module01.sjms.Lod.t1;
//相当于远程对象
public class Office {
public void closeOther(){
System.out.println("closeOther");
}
}