什么是
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");
}
}