软件工程

软件工程基础

  1. 软件工程:
    应用系统的,规范的,可量化的方法来开发,运行和维护软件,即将工程应用到软件。
    对1中各种方法的研究。

关键是子类扩展父类的时候,只能增加字段和方法,而不能增加约束。

长和宽必须相等是对父类中两个字段的约束,而在子类无法扩展这种约束,这算是目前oo语言的局限性。期待下一代oo语言解决。

“能够施行于base class对象上的每件事情,也可以施行于derived class对象身上”


这个就是“里氏替换原则”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Rectangle{
private double width;
private double height;

public void setWidth(double width) {
this.width = width;
}

public double getWidth() {
return width;
}

public void setHeight(double height) {
this.height = height;
}

public double getHeight() {
return height;
}

public double getPerimeter(){
return (width + height) * 2;
}

public double getArea(){
return width * height;
}
}

class Square extends Rectangle {

@Override
public void setWidth(double width) {
super.setWidth(width);
super.setHeight(width);
}

@Override
public void setHeight(double height) {
setWidth(height);
}
}

https://www.jianshu.com/p/eeefa13d6dbe

耦合度举例说明

内容耦合。当一个模块直接修改或操作另一个模块的数据时,或一个模块不通过正常入口而转入另一个模块时,这样的耦合被称为内容耦合。内容耦合是最高程度的耦合,应该避免使用之。

1
2
3
4
5
6
7
8
9
class A{
    public int data_a;
}
class B{
    public fun(){
        A a = new A();
        a.data_a = 5;
    }
}

这里B直接修改了A的data_a,所有是“内容耦合”;

公共耦合。两个或两个以上的模块共同引用一个全局数据项,这种耦合被称为公共耦合。在具有大量公共耦合的结构中,确定究竟是哪个模块给全局变量赋了一个特定的值是十分困难的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class C{
    int static data_x;
    int static data_y;
}

class A{
    public void fun(){
        C.data_x = 5;
    }
}
class B{
    public void fun(){
        C.data_x = 6;
    }
}

A和B都可以操作data_x,说以A和B是“公共耦合”

外部耦合 。一组模块都访问同一全局简单变量而不是同一全局数据结构,而且不是通过参数表传递该全局变量的信息,则称之为外部耦合。

1
2
3
4
5
6
7
8
9
10
11
int static data_x;
class A{
    public void fun(){
        data_x = 5;
    }
}
class B{
    public void fun(){
        data_x = 6;
    }
}

A和B都访问data_x,所以A和B是外部耦合。

控制耦合。一个模块通过接口向另一个模块传递一个控制信号,接受信号的模块根据信号值而进行适当的动作,这种耦合被称为控制耦合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A{
    private B mB;
    private int m_a= 4;
    public void update(){
        m_a= mB.get();
    }
}
class B{
    A mA;
    int m_b;
    public void fun(){
        data_x = 6;
    }
    public void set(int b){
        this.m_b =b;
        mA.update();
    }
}

当B.set()运行时,A的m_a也会从新设计,说以A和B是“控制耦合”

标记耦合。若一个模块A通过接口向两个模块B和C传递一个公共参数,那么称模块B和C之间存在一个标记耦合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class B{
    stiac void fun(int a){
    }
}
class C{
    static void fun(int a){
    }
}
class A{
    int m_a = 5;
    void fun(){
        B.fun(m_a );
        C.fun(m_a );
    }
}

A向B和C传递了共同的参数m_a ,所有B和C是标记耦合

数据耦合。模块之间通过参数来传递数据,那么被称为数据耦合。数据耦合是最低的一种耦合形式,系统中一般都存在这种类型的耦合,因为为了完成一些有意义的功能,往往需要将某些模块的输出数据作为另一些模块的输入数据。

1
2
3
4
5
6
7
8
9
class A{
void fun(int a);
}
class B{
void fun(A a){
int b;
a.fun(b);
}
}

模块A和B通过参数传递数据,所有A和B是“数据耦合”

非直接耦合 。两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A{
    int fun(){
    }
}
class B{
    void fun(int a){
    }
}
class Client{
    void main(){
        A a = new A();
        B b = new B();
        int i_a = a.fun();
        b.fun(i_a);
    }
}

A和B没有直接连接,他们的调动是通过Client来完成,说以A和B是“非直接耦合”

多项式加法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//定义节点类
class Node{
public int coef;//系数
public int exp;//指数
public Node next=null;//下个节点
public Node(){
coef=0;
exp=0;
}
public Node(int coef,int exp){
this.coef=coef;
this.exp=exp;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//多项式类
public class PolynList {
//多项式相加
public Node add(Node link1, Node link2) {
Node pre=link1;
Node qre=link2;
Node p=pre.next;
Node q=qre.next;
Node result=p;
while(p!=null && q!=null){
if(p.exp<q.exp){
pre=p;
p=p.next;
}else if(p.exp>q.exp){
Node temp=q.next;
pre.next=q;
q.next=p;
q=temp;
}else{
p.coef=p.coef+q.coef;
if(p.coef==0){
pre.next=p.next;
p=pre.next;
}else{
pre=p;
p=p.next;
}
qre.next=q.next;
q=qre.next;
}
}
if(q!=null){
pre.next=q;
}
return result;
}

//添加数据方法
public Node insert(Node link,int coef,int exp) {//添加节点
Node node=new Node(coef,exp);
if(link==null){
link.next=node;
}else{
Node temp=link;
while(temp.next!=null){
temp=temp.next;
}
temp.next=node;
}
return link;
}
}
//主方法
public static void main(String[] args) {
PolynList ts = new PolynList();
Node link1=new Node();
Node link2=new Node();
//第一个多项式
ts.insert(link1,4,0);
ts.insert(link1,5,2);
ts.insert(link1,4,8);
ts.insert(link1,6,12);
//第二个多项式
ts.insert(link2,6,1);
ts.insert(link2,6,3);
ts.insert(link2,3,8);
ts.insert(link2,4,15);
ts.insert(link2,8,20);

link1 = ts.add(link1, link2);

while(link1!=null){
if(link1.exp== 0)
System.out.print(link1.coef);
else
System.out.print(link1.coef+"x^"+link1.exp);
link1=link1.next;
if(link1!=null)
System.out.print("+");
}
}
}

栈(stack)
1).定义:插入和删除只能在表的一端进行的线性表.
     又称后进先出(LIFO--Last In First Out)
例子:饭店里的一堆碟子

队列(queue)
1) 定义:插入在一端进行,删除在另一端进行的线性
表.又称先进先出(FIFO:First In First Out)

递归的概念
若一个对象部分地包含它自己或用它自己给自己定义,则称这个对象是递归的。
若一个过程直接地或间接地调用自己,则称这个过程是递归的过程。

1
2
3
4
long factorial(long n)
{ if(n==0)return 1;//递归终结条件
else return n*factorial(n-1);//n问题化为n-1问题
}