面向对象编程中设计模式学习笔记

  上学期学的OOP,最近把期末复习笔记拿出来温习,共享一发。(一些图片发不上来,蛋疼···难怪觉得阅读起来不好理解。-。-! 待更新····)


---part 1 --------------------------------------------------------------------------------------------------

OOP基础知识(C#为例):

Polymorphism means many different form

 

If you have inheritance, you have polymorphism

 

Inheritance

Polymorphism

Abstraction

Encapsulation

Information hiding

Loose coupling

 

Hello.exe (an executable)

Hello.dll (an assembly of a library)

What is an assembly?

The smallest unit of a binary file in .NET, contains byte code from several source files in a project.

 

Static means global function

 

Main() is the entry point of an application

 

string[] list = { “apple”, “banana”, “cherry” };

 

List<string> list = new List<string>() { “apple”, “banana”, “cherry” };

Prefer Container over Array

 

Function overloading à You can have many functions with the same name, as long as their signatures are different. Signature = function name + parameter list.

return value is not part of signature

 

Single responsibility principle

 

OPEN-CLOSED PRINCIPLE (Bertrand Meyer)

Closed for modification

Don’t change existing code

Open for extension

Can add new code to satisfy the new requirements

 

Class level method

static keyword

Invoke by the class name, don’t need an object

E.g. Account.Foo()

Class method cannot have object attributes

If attributes are needed, they must be static

 

Class level attribute (static attribute)

Global attribute, access by class name

One copy per class

Access by class name, not object name

 

public methods and properties

Mark all word boundaries in uppercase

e.g. PascalCasing

 

 private interfaces and parameters

first letter is in lowercase

e.g. camelCasing

 

Since the object’s size may change at run time, the object cannot be stored in the stack

 

Parameter passing in C# is default by passing value (the copy of it, whatever it is int type or reference type).

Pass by value is safe because the caller’s program is not affected by the method

 

ref: Pass by reference .If you want to modify caller’s data

in: Parameter is passed by value, the default

out: Same as ref, but caller doesn’t need to initialize the value

params: To pass a varied number of parameters as a single argument

e.g. like the printf() in C

main() {

        Account s1=new Account(”001”);

        Account s2=new Account(”002”);

        Foo(s1, s2);                   //s1,s2 pass as params list

       }

       public static void Foo(params Account[] list){

 foreach (Account s in list)

   Console.WriteLine(s.Id);

       }

 

Why Upcasting is safe –

Because subclass supports all methods in baseclass

Upcasting is automatically allowed

 

Downcasting is dangerous

Treat baseclass as an subclass(object)

subclass may have more methods than baseclass

baseclass may not be able to support all methods in subclass

Can’t create a baseclass and use it as subclass

 

class can have both interface and implementation(code)

interface doesn’t have implementation(no attributes and no method detailed code), only function declaration or property

abstract class is a class that cannot be instantiated

The main purpose is to provide a base class that serves like interface, but also can have attribute and code

 

Difference between interface and abstract class

Interface

No implementation

Cannot be instantiated

Intent: purely for interface inheritance

 

Abstract base class

Can have interface and implementation

Cannot be instantiated

 

 

 

Solution to the diamond problem

 

RTTI – run time type identification

 

 

 

Cyclic Dependency may lead to problems

Solution:

No cyclic dependency within an assembly

Then make sure that there is no cyclic dependency (acyclic) between assemblies

 

Value Type class is a subclass of System.Object that overrides and changes the methods from reference-based to value-based

 

Shallow copy and deep copy

Shallow copy :

Student s1 = new Student(7,”James”);

Student s2 = s1;     //shallow copy

Only the address of s1 is copied to s2

 

For deep copy, use Clone() in ICloneable

 

考虑被调用的时候和返回值的时候来理解这个principle

因为subclass能代替baseclass来执行功能。

baseclass调用的条件一定能适用subclass à subclass weaken pre-condition

subclass 返回值 一定要适用于原本接收baseclass返回值的条件 àsubclass strengthen post-condition

Example:

Base class-- 

accept positive real number, return positive real number

 

Subclass--

Pre-condition

Accept all real number (OK)

Accept positive integer (Not OK)

Post-condition

Return all real number (Not OK)

Return positive integer (OK)

 

 

IEnumerable

Can’t use foreach because foreach does not know how to access StudentList since it is a user-defined container

 

Solution

Implement the IEnumerable interface

GetEnumerator() returns an IEnumerator object that is used by foreach to access the container

 

public Interface IEnumerable {

          IEnumerator GetEnumerator();

       }

 

public class StudentList : IEnumerable {

         private ArrayList list; 

         . . .

    public IEnumerator GetEnumerator() {

         //return the object that implements IEnumerator

         return list.GetEnumerator();

       }

}

 

foreach uses GetEnumerator() to get an IEnumerator object

 

The IEnumerator object has only three functions, but can be used to get objects in the container one by one

 

The three functions are

Reset( )- make 1st element as current object

MoveNext()– next object as current object

Current – Property that return the current object

 

 

Two keys features in generic programming

Template

Replace type by a parameter

One template for all types

 

Iterator 迭代

An abstraction of all kinds of sequential containers

It separates algorithms from data structures

Extremely useful

 

??Delegate object

 --part 2-----------------------------------------------------------------------------------------

Design pattern (设计模式):  

 

Creational pattern:

关于 Creational pattern(不知道怎么翻译,创建模式?),个人感觉主要是运用了OOP的继承性和多态的特点,即利用子类继承同一个父类而能够upcasting的特点,子类和父类及子类之间可以随意替换而不影响实现。

Parameterized factory methods

Factory method needs a new subclass for new product

Require many subclasses

 

Parameterized factory method

Use a parameter (instead of a new subclass) to identify a new kind of product

Reduce the number of subclasses

 

 

Abstract Factory provides an interface for creating families of related or dependent objects without specifying their concrete classes.(一套的class。 自由组合? Decorator patternPrototype factorypattern 能自由组合)

(builder 有点像另一个pattern?(答:template pattern,区别见template pattern)确定运作顺序,具体的操作不确定。但是builder仍然是做一套的class.)

 

Cilent 自己组织由abstractFactory 制作出来的classes

Compare between AbstractFactory and Builder

Builder 最后给的是成品。实际上只是construction的设计区别?不,builder的操作都是内部操作,最后得出的是一个builder.product().通常由director class的一个method来调用builder及设计构造的流程。

http://zhenyulu.cnblogs.com/articles/37378.html

 

 

Prototype factorypattern

prototypeFactory constructor 引进不同部件的组合。而具体的构造过程,调用了相应部件的clone()。从而实现了部件自由组合的factory method

 

以上四种pattern的对比总结

Factory Method  Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses

 

Abstract Factory  Provide an interface for creating families of related or dependent objects without specifying their concrete classes。(侧重于一套class,好比一套主题,一套服装搭配。但选用这个套装的哪些组件却由client决定,不是非要一整套全使用。)

 

Builder  Separate the construction of a complex object from its representation so that the same construction process can create different representations。(reuse 构造的过程和顺序,比如炒菜,炒肉片和炒青菜的流程是一样的,但是其中加的原料,佐料却可能不同。最终获得的是完整的一道菜。)

 

Prototype  Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype。(随意自由组合classes,关键在于constructorclone

--------------------分割线--------------------------------------------------------------------------

 

 

Singleton pattern:

关键在于2private 2 static 1public


Structural patterns:

Adapter pattern:两种类型,C#只支持object adapter

Intent

Convert the interface of a class into another interface clients expect.

Adapter lets classes work together that couldn’t otherwise because of incompatible 不相容的 interfaces

How about inherit the old system’s implementation and the new system’s  interface?

Still has problem - cannot hide the old implementation

OldSystem can be exposed by casting

                   ClassAdapter newSystem = new ClassAdapter()

                   OldSystem oldSystem = (OldSystem) newSystem;

 

Class and object adapters have different trade-offs.

A class adapter

· adapts Adaptee to Target by committing to a concrete Adapter class. As a

consequence, a class adapter won't work when we want to adapt a class and

all its subclasses.

· lets Adapter override some of Adaptee's behavior, since Adapter is a

subclass of Adaptee.

· introduces only one object, and no additional pointer indirection is needed

to get to the adaptee.

An object adapter

· lets a single Adapter work with many Adaptees—that is, the Adaptee itself

and all of its subclasses (if any). The Adapter can also add functionality

to all Adaptees at once.

· makes it harder to override Adaptee behavior. It will require subclassing

Adaptee and making Adapter refer to the subclass rather than the Adaptee

itself.

 

不同的平台用同样的interface实现不同的功能

 

Decorator:

从最特殊的开始,has-a 较普通的;较普通的has-a 更普通的。运作的时候,顺序刚好相反,最普通的先运作···顺序很重要,应确保满足特殊操作的前提条件。在此例中,最后的文字阅读取决于阅读流已经解码。

 

待补充---

每次运作,检查携带的decorator是不是null,不是就让它先执行操作;接着执行自己的操作

 

class Program

    // In Facade pattern, classes A and B in FacadeDLL assembly are hidden. Only the Facade //object is exposed.

    // Facade object is usually a singleton, but it is not implemented here.

    {

        static void Main(string[] args)

        {

            Facade facade = Façade.Instance();//singleton

 

            facade.Foo();  // act like a single simple object

            facade.Bar();

Mainsystemsubsystem 经常是不在一个assembly里面,在subsystem里创建一个façade class作为public代表,用has-a的关系调用其他internal class,运用delegate来执行操作。Façade singleton来保证唯一性。

            Console.ReadLine();

        }

}

 

public class Facade    //key word -- public

 {

        A objA;

        B objB;

        public Facade()

        {

            objA = new A();

            objB = new B();

        }

        public void Foo()

        {

            objA.Foo(); //delegate

        }

        public void Bar()

        {

            objB.Bar();//delegate

        }

 }

 

    internal class A      //key word -- internal

    {

        internal void Foo()

        {

            Console.WriteLine("A Foo() visited");

        }

    }

 

    internal class B      //key word -- internal

    {

        internal void Bar()

        {

            Console.WriteLine("B Bar() visited");

        }

    }

 

class ImageProxy : Graphic

    {

        Image image;    /* ImageProxy has a pointer to Image */

 

        public override void Draw()  /* initially, the new object only has a null reference */

        {                            /* Only when it is called to execute some function */

                                     /* it create the actual object */

           

            if (image == null)

            {          // do all the expensive processing here, e.g. get a large image file

                image = new Image()

                {

                    name = "-->large image file created"

精华在于偷懒,一开始放一个廉价的reference,真正被调用的时候才去“抱佛脚创建真的object

                };

            }

            image.Print();

        }

    }

 

 

Flyweight:

 

 

Behavioral patterns

How to use objects in a collaborative way

The key - identify the responsibilities of the objects```

 

Command pattern

Some relationship with delegate pattern?

 

Chain of Responsibility

Actually, in lecture case, also apply when need to satisfy all nodes’ requirement.

Core codes:

public override bool Enrol(Student s)/* the parameter is student type*/

 {

            bool flag = true;       //default is true, because enroll is a kind of request should //satifsfy all requirement

            if (s.courses.Count > 2)

                flag = false;       /* the student's courses can not be more than 2 */

 

            if (flag == false)

            {

                Console.WriteLine("University: Enrol failed, university does not allow student to enrol to more than 2 courses");

                return false;

            }

            else if (parent != null)   /* i.e.if flag == true,parent!= null */

                return parent.Enrol(s); // if flag == true, do further checking with parent

            else

                return true;       /*i.e.if flag == true,parent== null,return true */       

  }

        /* check whether meet with own requirement first,if yes then check the parent's  */

 

Another typical example:

    public abstract class Handler

    {

        protected Handler successor; //继承者,及上级或者父级

 

        public void SetSuccessor(Handler successor)

        {

            this.successor = successor;

        }

 

        public abstract void HandleRequest(int request);

    }

    public class ConcreteHandler2 : Handler    //具体的handler

    {

        public override void HandleRequest(int request)

        {

            if (request >= 10 && request < 20)   //如果请求在其解决能力内,就自行解决

            {

                Console.WriteLine("{0} handled request {1}", this.GetType().Name, request);

            }

 

            else if (successor != null) //如果无法解决,并且拥有上级,那就递交请求给上级

            {

                successor.HandleRequest(request);

            }

        }

}

    class Program

    {

        static void Main(string[] args)

        {

            // Setup Chain of Responsibility

            Handler h1 = new ConcreteHandler1();

            Handler h2 = new ConcreteHandler2();

            Handler h3 = new ConcreteHandler3();

 

            h1.SetSuccessor(h2);     //设置好继承者

            h2.SetSuccessor(h3);

Chain of responsibility decorator 的区别:Chain of responsibility大部分情况下只需要将请求递交到有权限的handler手里处理了之后,就结束了该流程。Decorator 则需要遍历所有的操作,直到没有下一个decorator

 


            // Generate and process request

            int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };

 

            foreach (int request in requests)

            {

                h1.HandleRequest(request);

            }

        }

    }

 

Observer pattern:

         Core codes:

 

C# ‘s delegation pattern ?delegation object ? keyword ?

 

My own example:

class Program

    {

        static void Main(string[] args)

        {

            Calculator cal = new Calculator();

            Call myCall = new Call(cal.check);

            Console.WriteLine("5 is {0} ", myCall(5));

            myCall = new Call(Calculator.flag);

            Console.WriteLine("-3 is used {0}", myCall(-3));

            Console.ReadLine();          

        }

    }

 

    public delegate string Call(int n); //do not know what exactly “Call” is; seems to be a //class,because can be initialized;also like a //method,because it can accept parameters and return //values.

    public class Calculator

    {

        public string check(int n)

        {

            if (n > 0)  return "positive";

            else if (n < 0)  return "negative";

            else  return "zero";

        }

 

        public static string flag(int n)

        {

            if (n > 0)  return " + ";

            else if (n < 0)  return " - ";

            else  return " 0 ";

        }

    }

http://www.cnblogs.com/hyddd/archive/2009/07/26/1531538.html

 

 

Mediator

// Intent: to communicate via a central coordinator which is called the mediator

// Observer pattern can also be used to communicate between different parties, but it is done

//without a central coordinator

    class Program

    {

        static void Main(string[] args)

        {

            Director dir = new Director(); //the mediator

            Widget listBox = new ListBox(dir);

            Widget entryField = new EntryField(dir);

 

            listBox.Changed();    // director is notified, and dir.WidgetChagned(ListBox w) is invoked, and all entryField are notified

 

            entryField.Changed(); // director is notified, and dir.WidgetChagned(EntryField w) is invoked, and all listBox are notified

            Console.ReadLine();

        }

    }

 

    class Director //the mediator

    {

        List<ListBox> listBoxList = new List<ListBox>();

        List<EntryField> entryFieldList = new List<EntryField>();

 

        public virtual void Add(ListBox w)           // function overloading

        {

            listBoxList.Add(w);

        }

        public virtual void Add(EntryField w)                   

        {

            entryFieldList.Add(w);

        }

 

        public virtual void WidgetChanged(Widget w)      // function overloading

        {

        }

 

        public virtual void WidgetChanged(ListBox w) //if ListBox change , notify entryField

        {

            foreach (EntryField item in entryFieldList)

            {

                item.SetText();

            }

        }

 

        public virtual void WidgetChanged(EntryField w)

        {

            foreach (ListBox item in listBoxList)

            {

                item.GetSelection();

            }

        }

    }

 

    class Widget

    {

        protected Director dir; // contain a mediator pointer

 

        public virtual void Changed()

        {

            dir.WidgetChanged(this);

        }

    }

 

    class ListBox : Widget

    {

        public ListBox(Director dir)  //constructor set up the association with mediator

        {

            this.dir = dir;

            dir.Add(this);

        }

 

        public override void Changed() //when changed, notify mediator

 {

     dir.WidgetChanged(this);

  }

 

        public void GetSelection()

        {

            Console.WriteLine("EntryField changed: ListBox is notified, GetSelection() is updated");

        }

    }

 

    class EntryField : Widget

    {

        public EntryField(Director dir)   //constructor set up the association with mediator        {

            this.dir = dir;

            dir.Add(this);

        }

 

        public override void Changed()//when changed, notify mediator

{

    dir.WidgetChanged(this);

}

 

        public void SetText()

        {

            Console.WriteLine("ListBox changed: EntryField is notified, SetText() is updated");

        }

}

 

Comparision between observer pattern and mediator pattern:

Mediator pattern is a kind of abserver pattern with a central coordinator, and mediator is more indirectional than observer.

 

 

Template pattern:

Template pattern somehow like the builder pattern, however builder pattern focuses on creating objects , template pattern could do more.

In template pattern, only the methods could be overridden and the secquencial steps are usually encapsulated inside a method(e.g. Run())

builder的区别:builderconstruction流程控制在director classmethod里;template的操作流程在自己的run()里。而且,builder的作用是创造一堆objecttemplate 是进行一系列操作。

 

State pattern:

My understanding:

Object à receive a request à delegate to its state by passing itself as parameter(for changeState of object later) à the state override the meaningful request’s handler, process the request and change object’s state by calling object.changeState()  OR  ignore the meaningless request whose handler method is defaultly defined in state base class.

Note: the state class could use singleton pattern because stateless (have no memory ,no local attributes)

 

Example codes:

    // The state machine below describes the state of a Book

    // A book has 2 states - IN or OUT

    // If a book is IN, and is invoked by a CheckOut command, then the state changed to OUT

    // If a book is OUT, and is invoked by a Return command, then the state changed to IN

    // Otherwise any other commands are ignored (e.g. a book is IN, and is invoked by a Return

//command, which is not meaningful

class Program

{

        static void Main(string[] args)

        {

            Book r = new Book();

            r.Return();                  //ignored

            r.CheckOut();                  //print CommandAB, move to state B

            r.CheckOut();                  //ignore

            r.Return();                  //print CommandBA, move to state A

            Console.ReadLine();

        }

    }

 

    class Book

    {

        State state;

 

        public Book()

        {

            state = In.Instance();  //singleton 

        }

 

        public void ChangeState(State nextState)

        {

            state = nextState;

        }

 

        public void CheckOut()

        {

            state.CheckOut(this);  //delegate to state , and pass itseif as parameter

        }

 

        public void Return()

        {

            state.Return(this);    //delegate to state , and pass itseif as parameter

        }

    }

 

    class State

    {                  /* Base class TCPState provides the dummy假的 default */

        public virtual void CheckOut(Book r) { Console.WriteLine("ignored"); }

        public virtual void Return(Book r) { Console.WriteLine("ignored"); }

    }

 

    class In : State

    {

        private static In objectIn;

 

        private In() { }                         //for singleton

 

        public override void CheckOut(Book r)  //only checkout request is meaningful to In state

        {

            Console.WriteLine("Checkout");

            r.ChangeState(Out.Instance());

        }

 

        public static State Instance()         //for singleton

        {

            if (objectIn == null)

                objectIn = new In();

 

            return objectIn;

        }

    }

 

    class Out : State

    {

        private static Out objectOut;

 

        private Out() { }

 

        public override void Return(Book r)// //only return request is meaningful to Out state

        {

 

            Console.WriteLine("Return");

            r.ChangeState(In.Instance());

        }

 

        public static State Instance()

        {

            if (objectOut == null)

                objectOut = new Out();

 

            return objectOut;

        }

}

 

Strategy Pattern:

Use delegation to encapsulate an algorithm so that your software can select between different algorithms flexibly

Compared with State pattern:

 

Visitor pattern:

   to add new functionality to a system.

Node usually has a tree (composite) structure

The visitor object transverses all nodes in the tree

Each node callbacks to the visitor; visitor provides the new functionality

 

To add new functionality

simply add a new subclass of visitor,

no need to modify the object structure (Node)

 

Sometime we would like to treat callback from Course and NodeList differently:

Solution by function overloading

Overload the callback function Visit(), so as to treat Course and NodeList differently

 

class Visitor {

 public void Visit(Course n) {//. . .}

 public void Visit(NodeList n){//. . .}

}

 

Another usage of Visitor Pattern – solve Double dispatch 派遣

Cause: C#  and Java support only single dispatch . Polymorphism is limited to the type of one object. (In other words, only when the object is the positive method executor, could it perform the factory method(be distinguished and execute different overridden methods))

 

 

Solution 1:  if-then-else block (…)

But it is low level

 

Memento pattern:

Participants

· Memento (SolverState)

-- stores internal state of the Originator object.

-- protects against access by objects other than the originator.

(Mementos have effectively two interfaces. Caretaker sees a narrow

interface to the Memento—it can only pass the memento to other objects.

Originator, in contrast, sees a wide interface, one that lets it

access all the data necessary to restore itself to its previous state.

Ideally, only the originator that produced the memento would be

permitted to access the memento's internal state.)

· Originator (ConstraintSolver)

-- creates a memento containing a snapshot of its current internal

state.

-- uses the memento to restore its internal state.

· Caretaker (undo mechanism)

-- is responsible for the memento's safekeeping.

-- never operates on or examines the contents of a memento

An approximate implementation in C# (Java)

Use internal so that only classes within the assembly can see the hidden information

OR C# Nested Class : A class inside a class, so that the inner class cannot be seen from outside of the class.

 

 

Interpreter pattern:

 

MVC pattern:

 

Linq Topic

To add new functionality to an existing type

1.       Visitor pattern

2.       Create an external method and pass the Account object to this method

3.       Helper Class static methode.g. Helper.Deposit(Acc,10)

4.       Extension method

 

4.1.  Extension method by delegate

4.2. Action - system provided generic delegate

Action – delegate with no return value

e.g. Action <T1>, Action <T1,T2>```

 

Func – delegate with return value

e.g. Func<TResult>,Func<T1,TResult>,Func<T1,T2,TResult>```

 

Predicate 断言-- Take an object of type T and return true or false

E,g. Predicate<T>```

4.3.   Anonymous method

5.       Linq:

List<int> mylist = list.Where(x=>x%2==0).ToList();

 

 

Difference between List and IEnumerable:

IEnumerable<int> mylist = list.Where(x=>x%2==0);

Can only supports the IEnumerator’s methods, cannot support indexing, e.g. mylist[2]

Usually work together with foreach

 

List<int> mylist = list.Where(x=>x%2==0).ToList();

Smart array, support indexing

 

Linq operations:

1.       Filtering -- Current type is not changed, just processed

e.g. List<int> mylist = list.Where(x=>x%2==0).ToList();

e.g. var sortedList = list.OrderBy(x=>x.region).ThenBy(x=>x.branch).ThenBy(x=>x.ID)

2.           Projection -- Return a new type

   e.g. var idList = list.Select(x=>x.ID).ToList();

// idList is a list of List<string>; Select() actually is not only “selecting” but “converting”

 

Find the total sum of balance:

Double sum = list.Sum(x=>x.balance);

 

Find the total sum in every branch office and stored them in a dictionary:

var branchSum = list.GroupBy(x=>x.branch) .ToDictionary(x=>x.Key, x=>x.Sum());

 

Expression<Func<int, int, int>> f1=(a,b)=>a*b;// Expression<>是种参数为delegate的函数

Func<int, int, int> mult = f1.Compile();//转化为能执行的函数

int result = mult(1,2);

Console.WriteLine(“Result {0}”, result);

(总结:第一步,Expression先定义出具体操;第二步,Compile()转化为能执行的函数;最后,调用函数)

 

 

Methodology:

Common 5 stages approach:

1.      Requirement model

To capture the users requirements

2.      Analysis model

Initial rough model of the system

3.      Design model

Detailed model, one-to-one mapping between the classes diagram and the implementation model

4. Implementation model

The code

5.       Test model

 

Use-case approach

Use cases describe how the system is used from a user view point, written in the language of users.

 

WaterFall mode

The traditional approach, still widely used

 

Main problem

Single Long cycle, can take a year to complete

 

Modern approaches prefer shorter cycle (from a day to a few weeks) that build the work incrementally, so that

Continuous and fast feedback to the users

Risks can be discovered earlier

Changes can be made more rapidly

 

The main problem with a waterfall model is that the development is based on a single and long cycle. Problems that were identified at later stage become expensive to correct. Both RUP and XP use an Iterative and Incremental Development approach. Development is based on many short cycles. Each cycle resembles a mini-waterfall model. It is more likely that problems can be discovered earlier and therefore are less expensive to correct.

 

The process is iterative

 

Describe the system in the language of the users

Traditional approach

requirements are in the formthe system shall do this and that . . . ”

 

Use cases approach

requirements from users’ point of view actor shall do this and that . . . ”

 

Identify the Actors

Actor is external to the system

Actors help us to find the use cases

Actors e.g. Borrower, Librarian ,System administrator

 

 

Testing:

Unit testing

To test one and only one unit, usually a class

Specification test  (black box test) -- Equivalent partitioning: An equivalent set is a set of conditions for which an object is supposed to behave similarly, so as to reduce the number of test cases

structure test (white box test)--    every statement has to be executed at least once

 

Integration testing

Usually use cases based -- Test one use case at a time

Integration and unit tests can be done together

 

System testing

Testing the entire system, typically from an end-user view

 

Test techniques:

Regression test 回归测试

Run the test every time you change the system

Main purpose is to verify old functionality still work

Important test, must be automated (e.g. JUnit)

 

Operational test

Test the system in normal operation over a long period

Use the system in the intended manner

Only normal mistakes are made

Measure mean-Time-To-Failure (MTTF)

 

Full-scale test

run the system on its maximum scale

System is used by many users

 

Performance test or capacity test

Measure the system performance under different loads

 

Overload test

Goes one step further than the full-scale test to see how the system behaves when it is overloaded

Should not expect normal performance but at least the system should not go down and catastrophe not to occur

 

Negative tests

Stress test that try to use the system in ways it is not designed for, so as to reveal system weaknesses

e.g. incorrect network configuration, insufficient hardware capacity, impossible work load

 

Tests based on requirements

Tests based on requirement specifications

 

Testing of the user documentation

to check the consistency一致性 between manuals and system behavior

 

 

Test-driven development  (TDD)

TDD Golden Rule

Never write code unless you have a test that requires it

 

Assert.AreEqual(expect, actual, 0.001, "Account not debited correctly");

 

RUP  (Rational Unified Process):

RUP development is divided into four phases:

Inception开始

Elaboration 详细阐述

Construction 构建

Transition 转换

 

Each phase is divided into iterations

Each iteration has 9 workflows (now called disciplines)

Business Modeling

Requirements

Analysis and Design

Implementation

Test

Deployment

Configuration and Change Management

Project Management

Environment

 

Each phase ends with a milestone

If the milestone cannot be met, ABORT the development

 

Extreme Programming (XP)

A lightweight and efficient approach, emphasizes on “continuous integration, relentless testing”

 

Uses short iterations

Very short iterations (a day to a few weeks)

Because requirements change, scheduling must be flexible

 

Continuous integration testing

Once code is ready, do integration test

Very fast development

 

Less emphasis on analysis and design

Requirements change, so spending too much time on analysis and design is costly

 

Rely on refactoring

Instead of spending much time on initial architecture, rely more on continuous redesign of the code

 

Emphasize on fast coding

Code, test, system integration in a few hours

Fast coding lead to messy code

Rely on simple design, refactoring and automatic testing

 

Less emphasis on documentation

 

Reliance on oral communications, tests and source code to communicate system structure and intent

Standup meeting

Pair programming

Workspace has no partition

 

CMM (Capability Maturity Model)

Purpose of CMM

To evaluate the software process capability of an organization

 

 

你可能感兴趣的:(面向对象编程中设计模式学习笔记)