'개발방법론/모델링'에 해당되는 글 122건

  1. 2007.04.05 [링크자료] 테스팅 관련 (추후 업데이트)
  2. 2005.07.29 SEDA : An Architecture for Highly Concurrent Server Applications 1
  3. 2005.07.01 [POSA] MicroKernel 의 적용 사례
  4. 2005.03.25 Design Better Software with the Inversion of Control Pattern
  5. 2005.03.25 Working with Object-Orientation in UML
  6. 2005.03.25 UML Sequence Diagrams
  7. 2005.03.25 UML Class Diagrams for Java Programmers
  8. 2005.03.25 Working with Class Diagrams
  9. 2005.03.08 Roadmap to Agile methods and tools
  10. 2005.02.12 [onjava] Mock Objects in Unit Tests
  11. 2004.04.19 Extreme Programming
  12. 2004.02.10 continuous integration ..
  13. 2004.02.10 Cactus Classpath 셋팅
  14. 2004.01.29 J2EE 기반 개발에서의 테스트에 필요한 것들 정리..
  15. 2004.01.19 프로젝트를 위한 Tools12 (for Java ) : 프레임워크 관련
  16. 2004.01.19 프로젝트를 위한 Tools11 (for Java ) : 화면UI 관련
  17. 2004.01.19 프로젝트를 위한 Tools10 (for Java ) : Class보안 관련
  18. 2004.01.19 프로젝트를 위한 Tools9 (for Java ) : 요구사항정리 관련
  19. 2004.01.19 프로젝트를 위한 Tools8 (for Java ) : Graph 관련
  20. 2004.01.19 프로젝트를 위한 Tools7 (for Java ) : Report 관련
  21. 2004.01.19 프로젝트를 위한 Tools6 (for Java ) : DB 관련
  22. 2004.01.19 프로젝트를 위한 Tools5 (for Java ) : BP 관련
  23. 2004.01.19 프로젝트를 위한 Tools4 (for Java ) : Test 관련
  24. 2004.01.19 프로젝트를 위한 Tools3 (for Java ) : charts 관련
  25. 2004.01.19 프로젝트를 위한 Tools2 (for Java ) : 개발환경 관련
  26. 2004.01.19 프로젝트를 위한 Tools1 (for Java ) : Project 관리
  27. 2003.08.03 Refactoring Workbook - Source Code
  28. 2003.08.03 Refactoring Workbook
  29. 2003.08.03 Refactoring To Patterns
  30. 2003.08.03 Errata for Refactoring

Posted by 아름프로
My Ph.D. thesis work at UC Berkeley focused on the development of a robust, high-performance platform for Internet services, called SEDA. The goal is to build a system capable of supporting massive concurrency (on the order of tens of thousands of simultaneous client connections) and avoid the pitfalls which arise with traditional thread and event-based approaches.

SEDA is an acronym for staged event-driven architecture, and decomposes a complex, event-driven application into a set of stages connected by queues. This design avoids the high overhead associated with thread-based concurrency models, and decouples event and thread scheduling from application logic. By performing admission control on each event queue, the service can be well-conditioned to load, preventing resources from being overcommitted when demand exceeds service capacity. SEDA employs dynamic control to automatically tune runtime parameters (such as the scheduling parameters of each stage), as well as to manage load, for example, by performing adaptive load shedding. Decomposing services into a set of stages also enables modularity and code reuse, as well as the development of debugging tools for complex event-driven applications.

Our current prototype of a SEDA-based services platform is called Sandstorm. Sandstorm is implemented entirely in Java and uses the NBIO package to provide nonblocking I/O support. Support for the JDK 1.4 java.nio package is included as well. Despite using Java, we have achieved performance that rivals (and sometimes exceeds) that of C/C++. We have also implemented a SEDA-based asynchronous SSL and TLS protocol library, called aTLS. All of this software is available for download below.

We have built a number of applications to demonstrate the SEDA framework. Haboob is a a high-performance Web server including support for both static and dynamic pages that outperforms both Apache and Flash (which are implemented in C) on a SPECWeb99-like benchmark. Other applications include a Gnutella packet router and Arashi, a Web-based email service similar to Yahoo! Mail.

The best place to start for more information is the SOSP'01 paper on SEDA and the corresponding talk slides. My Ph.D. thesis has much more information as well. If you have questions, comments, or are interested in collaborations, please feel free to contact me by e-mail (see my home page).

Posted by 아름프로
Apache의 Geronimo
http://wiki.apache.org/geronimo/MicroKernel

Aapache의 Hivemind
http://wiki.apache.org/jakarta-hivemind/FrontPage?highlight=%28MicroKernel%29

여기에 JBoss의 Architecture에 보면..
Microkernel Layer 가 있다.
http://www.jboss.org/products/jbossas/architecture
Posted by 아름프로











Design Better Software with the Inversion of Control Pattern




The Inversion of Control pattern facilitates reuse, loose coupling, and easy testing of software components. Learn how to use it in your software design.

he Inversion of Control (IoC) pattern, also known as Dependency Injection, has recently become popular in the J2EE community. Several open source projects, including Spring, PicoContainer, and HiveMind, use the IoC pattern to develop lightweight J2EE Containers.


IoC is not a new concept, however. It has been around for several years now. Using object-oriented design principles and features such as interface, inheritance, and polymorphism, the IoC pattern enables better software design that facilitates reuse, loose coupling, and easy testing of software components. This article discusses IoC and demonstrates how to use this pattern in your software design without having to implement any of the open source frameworks.


IoC Design Pattern

Assume Class A has a relationship with Class B: it wants to use the services of Class B. The usual way to establish this relationship is to instantiate Class B inside Class A. Though this approach works, it creates tight coupling between the classes. You can't easily change Class B without modifying Class A. To eliminate the coupling, you can have a Configurator inject the instance of Class B (Object "b") to the instance of Class A (Object "a"). If you want to change the implementation of Class B later on, you simply change the Configurator object. So, the control of how Object "a" gets the reference of Object "b" is inverted. Object "a" is not responsible for getting the reference to Object "b". Instead, the Configurator is responsible for it. This is the basis for the IoC design pattern.





Figure 1. Object "a" Directly Creates Object "b"


To demonstrate the benefits of the Configurator object in this case, the following examples show a simple design without IoC and one with IoC (click here to download the sample code for this article).


Listing 1 and Figure 1 are simple examples in which Class A uses Class B:


public class A{
private B b;

public A(){
b=new B();
}

Listing 1. Class A Directly Refers Class B


Listing 1 assumes the following design decisions:


  1. Class A needs a reference to Class B.

  2. Class B is a concrete class that has a default constructor.

  3. Class A owns the instance of class B.

  4. No other class can access the instance of Class B.






Figure 2. Object "a" First Creates Object "c" and Then Object "b" by Passing Object "c"


If any one of the above design decisions change, then the code in Listing 1 must be modified. For example, if Class B changed to have a non-default constructor, which takes Class C (see Figure 2), then Listing 1 would change to Listing 2.


public class A{
private B b;

public A(){
C c=new C();
b=new B(c);
}

Listing 2. Class A Directly Refers Class B and Class C


Once again, Listing 2 assumes certain design decisions. Now Object "a" owns both Object "b" and Object "c". If Class B or Class C changes at all, then Class A needs to change as well. In essence, a simple design of a simple class with implicit design assumptions becomes a maintenance nightmare in the future. Consider how difficult making changes would be if you had this scenario in a typical application with several classes.


Alternatively, if you use a framework that uses the IoC pattern, the responsibility of creating Object "b" moves from Object "a" to the IoC framework, which creates and injects Object "b" into Object "a". This insulates Class A from the changes in Class B. Before Object "a" is used, it needs the reference to Object "b". The IoC framework will inject Object "b" into Object "a".





Figure 3. IoC Framework Creates Object "b" and Sets It to Object "a"


Listing 3 shows Class A from the previous listings modified to use the IoC pattern.


public class A{
private B b;

public A(){
}

public setB(B b){
this.b=b;
}

}

Listing 3. Class A Gets the Reference to Class B via setB


Listing 3 assumes the following design decisions:


  1. A needs a reference to B, and it doesn't need to know how B is instantiated.

  2. B can be an interface, an abstract class, or a concrete class.

  3. Before the instance of Class A is used, it needs a reference to the instance of Class B.



From the above design decisions, you can see that there is no tight coupling between Class A and Class B. Both can be changed independently without affecting each other. Of course, if there is any change in the public methods of Class B, Class A needs to change as well. But how Object "b" is created and managed is not decided in the implementation of Object "a". Instead, the IoC framework uses the setB() method in Object "a" to inject Object "b" (see Figure 3).



















IoC Frameworks

Several open source IoC frameworks like Spring, PicoContainer, and HiveMind support the IoC pattern. While the general IoC principle is simple, each of these frameworks supports different implementations and offers different benefits. The IoC pattern can be implemented in three ways: setter based, constructor based, and interface based. This section briefly discusses each of them. For more in-depth details, refer to the frameworks' home pages.


Setter-Based IoC

This type of IoC uses a setter method to inject the referenced object into a referring object. This is the most common type of IoC, and both Spring and PicoContainer implement it. Setter-based IoC is good for objects that take optional parameters and objects that need to change their properties many times during their lifecycles. Its main disadvantage is that you need to expose all the properties of an object to the outside world when using a setter method. This breaks one of the key OO principles: data encapsulation and information hiding.


Constructor-Based IoC

This type of IoC uses a constructor to set the reference of the object. Its main advantage is that only the creator knows about the referenced object. Once the object is created, the client code that uses the object is unaware of the referenced object. This approach may not work in all types of applications, however. For example, if you use an external API that needs a default constructor, then you need to go with a setter-based IoC. A constructor-based IoC is the main type of implementation in Spring.


Interface-Based IoC

In this type of IoC, objects implement a specific interface from the IoC framework, which the IoC framework will use to properly inject the objects. One of the main advantages of this type is that it doesn't need an external configuration file to configure the object references. Since you need to use the IoC framework's marker interface, the IoC framework knows how to glue the objects together. It is similar to using EJB. Any EJB container knows how to instantiate your objects and hook them with itself. The main disadvantage of this approach is that the marker interface ties your application to a specific IoC framework. Apache Avalon is based on this approach but this project has been closed.


An Example of IoC

If you are starting a new project, you can choose any of the open source IoC frameworks based on your needs. If you want to use the IoC pattern in your existing project then you need to write your own classes that support IoC. Though the open source frameworks offer off-the-shelf components and may provide many more features than your own implementation, you can still develop a set of classes that support the IoC pattern. This section demonstrates how.


Say you want to write a CustomerService object to process customer data. Assume customer data is stored in two different places: a relational database and an XML file. You also want to have CustomerService create Customer objects by reading data from either the database or the XML file. Now, say you want to accomplish this without changing the source code of CustomerService to switch between the database and XML file.


DataSource

First, design an interface (see Listing 4) and define common methods, which you will use to retrieve and store customer data. Both XMLDataSource and JDBCDataSource classes implement this interface.


public interface DataSource {
public Object retrieveObject();
public void setDataSourceName(String name);
public String getDataSourceName();
public void storeObject(Object object);
}

Listing 4. Common Interface to Customer Data


XMLDataSource

Listing 5 shows a class that implements DataSource and provides an implementation that uses an XML file to retrieve and store customer data.


public class XMLDataSource implements DataSource {
private String name;

/**
* Default Constructor
*/
public XMLDataSource() {
super();
}

/**
* Retrieve Customer data from XML Source and construct
* Customer object
*/
public Object retrieveObject() {
//get XML data, parse it and then construct
//Customer object
return new Customer("XML",10);
}

/**
* Set the DataSource name
*/
public void setDataSourceName(String name) {
this.name=name;
}

/**
* Return DataSource name
*/
public String getDataSourceName() {
return name;
}

/**
* Store Customer into XML file
*/
public void storeObject(Object object) {
//Retrieve customer data and store it in
//XML file

}

}

Listing 5. Class to Retrieve Customer Data from XML File


RelationalDataSource

The class in Listing 6 also implements DataSource and provides the same implementation as XMLDataSource with only one difference: this class retrieves and stores customer data using a relational database.


public class RelationalDataSource implements DataSource {
private String name;

/**
* Default constructor
*/
public RelationalDataSource() {
super();
}

/**
* Using the DataSource retrieve data for Customer and build a
* Customer object to return it to the caller
*/
public Object retrieveObject() {
//get data for Customer object from DB and create a
//Customer object
return new Customer("Relational",10);
}

/**
* Set the DataSource name
*/
public void setDataSourceName(String name) {
this.name=name;
}

/**
* Return the name of the DataSource
*/
public String getDataSourceName() {
return name;
}

/**
* Store Customer into relational DB
*/
public void storeObject(Object object) {
//store the customer data into Relational DB

}

}


Listing 6. Class to Retrieve Customer Data from Relational DB


















Customer

The simple class in Listing 7 holds customer data, which either the XMLDataSource or RelationalDatSource object will construct.

public class Customer {
private String name;
private int age;

/**
* Default Constructor
*/
public Customer(String name, int age) {
this.name=name;
this.age=age;

}

/**
* @return Returns the age.
*/
public int getAge() {
return age;
}
/**
* @param age The age to set.
*/
public void setAge(int age) {
this.age = age;
}
/**
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param name The name to set.
*/
public void setName(String name) {
this.name = name;
}
}

Listing 7. Class That holds Customer Data


CustomerService

This class in Listing 8 has a reference to DataSource, which it uses to retrieve and store Customer objects. The actual implementation of DataSource will be either XMLDataSource or RelationalDataSource, which will be injected into the CustomerService object. The constructor of the CustomerService object accepts a concrete implementation of the DataSource object and uses it to retrieve and store customer data.


public class CustomerService {
private DataSource dataSource;
private Customer customer;

/**
* Constructor in which DataSource object is injected. Based on the
* ioc.properties this object can either refer to RelationlDataSource or
* XMLDataSource
*/
public CustomerService(DataSource dataSource) {
super();
this.dataSource=dataSource;
customer=(Customer)dataSource.retrieveObject();
}

/**
* Modify Customer name
* @param name
*/
public void updateCustomerName(String name) {
customer.setName(name);
}

/**
* Modify Customer age
* @param age
*/
public void updateCustomerAge(int age){
customer.setAge(age);
}

/**
*
* @return Customer name
*/
public String getCustomerName(){
return customer.getName();
}

/**
*
* @return Customer age
*/
public int getCustomerAge(){
return customer.getAge();
}

}

Listing 8. CustomerService Class That Gets DataSource Reference via ServiceConfigurator





Figure 4. IoC Using ServiceConfigurator


ServiceConfigurator

The ServiceConfigurator in Listing 9 is a main class that uses the IoC pattern to inject the concrete implementation of DataSource into the CustomerService object. It reads the configuration parameters (see Figure 4) from the ioc.properties file and decides to create either an XMLDataSource or a RelationalDataSource object. The DataSource object is created using its default Constructor, and the name of the DataSource is set using its setter method. The created DataSource object is injected into CustomerService using its constructor, which accepts a DataSource reference. The created CustomerService object is stored in the ServiceConfigurator registry so that it will be returned when a subsequent request comes for the CustomerService object.


Figure 4 shows the inner workings of ServiceConfigurator, and Figure 5 shows the UML diagram for all of the classes explained previously. You can switch between XMLDataSource and RelationalDataSource just by editing the ioc.properties file.


public class ServiceConfigurator {
public static final String IoC_CONFIG_FILE="ioc.properties";
private Properties props;
private HashMap serviceRegistery;
private static ServiceConfigurator thisObject;

/**
* This method first checks if there is a ServiceConfigurator instance
* exist, if not creates a one, stored it and returns it
* @return
*/
public static ServiceConfigurator createServiceConfigurator(){
if(thisObject==null){
thisObject=new ServiceConfigurator();
}
return thisObject;
}

/**
* Private Constructor makes this class singleton
*/
private ServiceConfigurator() {
props = new Properties();
serviceRegistery=new HashMap();
loadIoCConfig();
createServices();
}

/**
* Load the IoC_CONFIG_FILE properties file
*
*/
public void loadIoCConfig(){
InputStream is = this.getClass().getClassLoader().getResourceAsStream(IoC_CONFIG_FILE);
try {
props.load(is);
is.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* Create the CustomerService by getting the DataSource name from the
* properties file. The CustomerService object is stored in the
* serviceRegistery so that it will be retrieved when requested.
* During the construction of CustomerService the DataSource object
* is injected into it. So the CustomerService can access the DataSource
* to retrieve the Customer.
*
*/
public void createServices(){
String dataSourceName=props.getProperty("dataSource");
DataSource dataSource=null;
if(dataSourceName!=null){
try {
dataSource=(DataSource)Class.forName(dataSourceName).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//name of the DataSource is retrieved from the properties file
dataSource.setDataSourceName(props.getProperty("name"));
CustomerService customerService=new CustomerService(dataSource);
serviceRegistery.put(CustomerService.class,customerService);
}
/**
* Stored Service is retrieved from serviceRegistery for the given
* Class object
*
* @param classObj
* @return
*/
public Object getService(Class classObj){
return serviceRegistery.get(classObj);
}

}


Listing 9. ServiceConfigurator that Uses IoC to Inject DataSource into CustomerService





Figure 5. ServiceConfigurator UML Class Diagram



The ServiceConfigurator is a simple class that supports the IoC pattern. You can modify it to add more features such as simultaneously supporting multiple DataSource objects, dynamically injecting the DataSource into CustomerService, and life cycle management.


CustomerServiceTester

The class in Listing 10 is a JUnit test that uses CustomerService. It uses ServiceConfigurator to retrieve the CustomerService object, which is used to change the Customer name and age.


public class CustomerServiceTester extends TestCase{
private ServiceConfigurator serviceConfig;

/**
*Default Constructor
*/
public CustomerServiceTester() {
super();
}

/**
* Create ServiceConfigurator
*/
public void setUp() throws Exception{
super.setUp();
serviceConfig=ServiceConfigurator.createServiceConfigurator();
}
/**
* Test CustomerService and check for Customer
* @throws Exception
*/
public void testCustomerService() throws Exception{
CustomerService custService=(CustomerService)serviceConfig.getService(CustomerService.class);
assertNotNull(custService);
custService.updateCustomerAge(30);
custService.updateCustomerName("Mani");
assertEquals(30,custService.getCustomerAge());
assertEquals("Mani",custService.getCustomerName());


}


Listing 10. JUnit Test that Uses CustomerService


















Service Configurator vs. Service Locator

The implementation of ServiceConfigurator in Listing 9 may lead you to think that there is no difference between the ServiceConfigurator class that uses IoC and one that uses the Service Locator pattern. In fact, you can modify the CustomerService in Listing 8 to use a Service Locator, which will give the CustomerService class either an XMLDataSource or a RelationalDataSource object, based on the Service Locator's internal implementation. By changing the internal implementation of Service Locator, you can switch the DataSource from which CustomerService gets its Customer. In this context, both Service Locator and ServiceConfigurator provide the same functionality to CustomerService. The main difference is how CustomerService gets the DataSource reference. In Service Locator, CustomerService must get the DataSource reference directly from Service Locator, while in ServiceConfigurator, CustomerService gets the DataSource indirectly through ServiceConfigurator.


So, what is the advantage of using Service Locator instead of ServiceConfigurator? ServiceConfigurator frees CustomerService from either acquiring or instantiating the DataSource directly. This makes CustomerService easy to test: simply inject the appropriate DataSource into it. More over, as explained previously in Listing 1 and Listing 2, because you do not make any assumptions about how CustomerService will get the DataSource reference, you can reuse the CustomerService object in different applications. This is the main advantage of using Service Configurator over Service Locator.


What to Inject?

In Figure 5, you see that CustomerService has a relationship with both the DataSource and the Customer classes. Yet this discussion has been about how to inject DataSource into CustomerService. Why not inject Customer into CustomerService? In fact, it is perfectly legitimate to make the ServiceConfigurator inject the Customer object into CustomerService by creating an interface for Customer and referencing it in CustomerService. It all depends on your application requirements and how you want to design the CustomerService class. The previous example made DataSource responsible for creating and storing the Customer object and created a tight coupling between DataSource and Customer. In the future, any change in the Customer class will require changes to all of the implementations of DataSource. However, the design decision was made with the assumption that the public methods of Customer would not undergo any changes, and if any changes occurred in the internals of Customer, then they will not affect the DataSource.


The only anticipated change is how the Customer data is retrieved and stored. Currently, the Customer data is stored in a relational database or in an XML file. Perhaps in the future, it might be stored in an object database or retrieved via a Web service. In either scenario, you can have new classes retrieve and store Customer data. So, based on these assumptions, the example injects only the DataSource into CustomerService, which is used to retrieve and store Customer data.


Add on to Simple Example

This article discussed the IoC pattern and briefly discussed open source frameworks that use it. It also discussed how you could incorporate the IoC pattern in your existing applications using the ServiceConfigurator example. Though simple, the ServiceConfigurator class supports the IoC pattern and provides all of its benefits. You can modify the ServiceConfigurator to add more features as you need for your applications.



Mani Malarvannan is a consultant at Cybelink Systems. He has been developing Web-based applications using object-oriented methodologies and software patterns for several years.






Posted by 아름프로


Working with Object-Orientation in UML


                                Date: Jun 25, 2004 By Joseph Schmuller.
                                Sample Chapter is provided courtesy of Sams.
                                        
Are you trying to learn about object-oriented programming (or at least how to make the most of it) while you're also coming up to speed with UML? In this sample book chapter, you'll firm up your knowledge of object-orientation as you learn more about the UML. Learn about attributes, operations, visualization, and classes.

What You'll Learn in This Hour:



      
  • How to model a class

  •   
  • How to show a class's features, responsibilities, and constraints

  •   
  • How to discover classes


Now it's time to put the UML together with the object-oriented concepts
  you learned in the last hour. In this hour, you'll firm up your knowledge
  of object-orientation as you learn more about the UML.


Visualizing a Class


As I pointed out in the first hour, a rectangle is the icon that represents
  a class in the UML. From Hours 1, "Introducing the UML," and 2, "Understanding
  Object-Orientation," recall that the name of the class is, by convention,
  a word with an initial uppercase letter. It appears near the top of the rectangle.
  If your class has a two-word name, join the two words together and capitalize
  the first letter of the second word (as in WashingMachine in Figure
  3.1
).


Another UML construct, the package, can play a role in the name of a class.
  As I pointed out in Hour 1, a package is the UML's way of organizing a
  diagram's elements. As you might recall, the UML represents a package as
  a tabbed folder. The package's name is a text string (see Figure
  3.2
).


Figure 3.1Figure
  3.1
The UML class icon.



Figure 3.2Figure
  3.2
A UML package.



If the WashingMachine class is part of a package called Household,
  you can give it the name Household::WashingMachine. The double colons
  separate the package name on the left from the classname on the right. This
  type of classname is called a pathname (see Figure
  3.3
).


Figure 3.3Figure
  3.3
A class with a pathname.




Attributes


An attribute is a property of a class. It describes a range of values that
  the property may hold in objects (that is, in instances) of that class.
  A class may have zero or more attributes. By convention, a one-word attribute
  name is written in lowercase letters. If the name consists of more than one
  word, the words are joined and each word other than the first word begins with
  an uppercase letter. The list of attribute names begins below a line separating
  them from the classname, as Figure 3.4
  shows.


Figure 3.4Figure
  3.4
A class and its attributes.



Every object of the class has a specific value for every attribute. Figure
  3.5
presents an example. Note that an object's name begins with a lowercase
  letter, precedes a colon that precedes the classname, and the whole name is
  underlined.



Naming Objects . . . or Not


The name myWasher:WashingMachine is a
named instance. It's also possible to have an anonymous instance like
:WashingMachine.



  

Figure 3.5Figure
  3.5
An object has a specific value for every one of its class's attributes.



  

The UML gives you the option of indicating additional information for attributes.
    In the icon for the class, you can specify a type for each attribute's
    value. Possible types include string, floating-point number, integer, and
    Boolean (and other enumerated types). To indicate a type, use a colon to separate
    the attribute name from the type. You can also indicate a default value for
    an attribute. Figure 3.6 shows these
    ways of specifying attributes.


  

Figure 3.6Figure
  3.6
An attribute can show its type as well as a default value.




Naming Values


An enumerated type is a data type defined by a list of named values. Boolean,
for instance, is an enumerated type because it consists of the values
"true" and "false." You can define your own enumerated types
like State, which consists of the values "solid," "liquid,"
and "gas."




Operations


An operation is something a class can do, and hence it is something that you
  (or another class) can ask the class to do. Like an attribute name, an operation's
  name is all in lowercase if it's one word. If the name consists of more
  than one word, join the words and begin all words after the first with an uppercase
  letter. The list of operations begins below a line that separates the operations
  from the attributes, as in Figure 3.7.


Figure 3.7Figure
  3.7
The list of a class's operations appears below a line that separates
  them from the class's attributes.



Just as you can indicate additional information for attributes, you can
indicate additional information for operations. In the parentheses that follow
an operation name, you can show the parameter that the operation works on, along
with that parameter's type. One kind of operation, the function, returns a
value after it finishes doing its work. For a function, you can show the value
it returns and that value's type.


These pieces of information about an operation are called the operation's
  signature. Figure 3.8 shows a couple
  of ways to represent the signature. The first two operations show the type of
  the parameter. The third and fourth show the type of the return value.


Figure 3.8Figure
  3.8
Signatures for operations.




Attributes, Operations, and Visualization


We've been dealing with classes in isolation thus far and showing all
  the attributes and operations of a class. In practice, however, you'll
  show more than one class at a time. When you do that, it's typically not
  useful to always display all the attributes and operations. To do so might make
  the diagram way too busy. Instead, you can just show the classname and leave
  either the attribute area or the operation area empty (or leave them both empty),
  as Figure 3.9 shows.


Figure 3.9Figure
  3.9
In practice, you don't always show all of a class's attributes
  and operations.



Sometimes it might be helpful to show some (but not all) of the attributes
  or operations. To indicate that you've only shown some of them, you follow
  the list of the ones you've shown with three dots ". . . ". This
  is called an ellipsis, and omitting some or all of the attributes or operations
  is called eliding a class. Figure 3.10
  shows the use of an ellipsis.


Figure 3.10Figure
  3.10
An ellipsis indicates that the displayed attributes or operations aren't
  the whole set.



If you have a long list of attributes or operations, you can use a keyword
  to organize in ways that will make the list comprehensible. As I mentioned in
  Hour 1, a keyword is enclosed inside two pairs of small angle brackets called
  guillemets. For an attribute list, you can use a keyword as a heading
  for a subset of the attributes, as in Figure
  3.11
.


Figure 3.11Figure
  3.11
You can use a keyword to organize a list of attributes or operations.












Responsibilities and Constraints


The class icon enables you to specify still another type of information about
a class. In an area below the operations list, you can show the class's
responsibility. The responsibility is a description of what the class has to
do—that is, what its attributes and operations are trying to accomplish. A
washing machine, for example, has the responsibility of taking dirty clothes as
input and producing clean clothes as output.


In the icon, you indicate responsibilities in an area below the area that contains
  the operations (see Figure 3.12).


Figure 3.12Figure
  3.12
In a class icon, you can write the class's responsibilities in
  an area below the operations list area.



The idea here is to include enough information to describe a class in an
unambiguous way. Indicating the class's responsibilities is an informal way
to eliminate ambiguity.


A slightly more formal way is to add a constraint, a free-form text enclosed
  in curly brackets. The bracketed text specifies one or more rules the class
  follows. For example, suppose in the WashingMachine class you wanted
  to specify that the capacity of a washer can be only 16, 18, or 20 pounds (and
  thus "constrain" the WashingMachine class's capacity
  attribute). You would write {capacity = 16 or 18 or 20 lbs} near the
  WashingMachine class icon. Figure
  3.13
shows how to do it.


Figure 3.13Figure
  3.13
The rule in curly brackets constrains the capacity attribute to be
  one of three possible values.




More on Constraints



The UML works with still another—and much more formal—way of adding
constraints that make definitions more explicit. It's an entire language
called Object Constraint Language (OCL). An advanced and sometimes useful tool,
OCL has its own set of rules, terms, and operators. The Web site of the Object
Management Group
(http://www.omg.org) provides
documentation on OCL.




Attached Notes


Above and beyond attributes, operations, responsibilities, and constraints,
you can add still more information to a class in the form of notes attached to
the class.


You'll usually add a note to an attribute or operation. Figure
  3.14
shows a note referring to a government standard that tells where to
  find out how serial numbers are generated for objects in the WashingMachine
  class.


Figure 3.14Figure
  3.14
An attached note provides further information about the class.



Bear in mind that a note can contain a graphic as well as text.



Classes—What They Do and  How to Find Them


Classes are the vocabulary and terminology of an area of knowledge. As you
talk with clients, analyze their area of knowledge, and design computer systems
that solve problems in that area, you learn the terminology and model the terms
as classes in the UML.


In your conversations with clients, be alert to the nouns they use to
describe the entities in their business. Those nouns will become the classes in
your model. Be alert also to the verbs that you hear because these will
constitute the operations in those classes. The attributes will emerge as nouns
related to the class nouns. After you have a core list of classes, question the
clients as to what each class is supposed to do within the business. Their
answers will tell you the class responsibilities.


Suppose you're an analyst building a model of the game of basketball,
and you're interviewing a coach in order to understand the game. The
conversation might go something like this:


Analyst: "Coach, what's basketball all about?"


Coach: "The goal of the game is to shoot the ball through the
basket and score more points than your opponent. Each team consists of five
players: two guards, two forwards, and a center. Each team advances the ball
toward the basket with the objective of ultimately shooting the ball through the
basket."


Analyst: "How does it advance the ball?"


Coach: "By dribbling and passing. But the team has to take a shot
at the basket before the shot clock expires."


Analyst: "Shot clock?"


Coach: "Yes. That's 24 seconds in the pros, 30 seconds in
international play, and 35 seconds in college to take a shot after a team gets
possession of the ball."


Analyst: "How does the scoring work?"


Coach: "Each basket counts two points, unless the shot is from
behind the three-point line. In that case, it's three points. A free throw
counts one point. A free throw, by the way, is the penalty a team pays for
committing a foul. If a player fouls an opponent, play stops and the opponent
gets to shoot at the basket from the free-throw line."


Analyst: "Tell me a little more about what each player
does."


Coach: "The guards generally do most of the dribbling and
passing. They're typically shorter than the forwards, and the forwards are
usually shorter than the center. All the players are supposed to be able to
dribble, pass, shoot, and rebound. The forwards do most of the rebounding and
intermediate-range shooting, while the center stays near the basket and shoots
from close range."


Analyst: "How about the dimensions of the court? And by the way,
how long does a game last?"


Coach: "In international play, the court is 28 meters long by 15
meters wide. The basket is 10 feet off the ground. In the pros, a game lasts 48
minutes, divided into four 12-minute quarters. In college and international
play, it's 40 minutes divided into two 20-minute halves. A game clock keeps
track of the time remaining."


This could go on and on, but let's stop and take stock of where we are.
Here are the nouns you've uncovered: ball, basket, team, players, guards,
forwards, center, shot, shot clock, three-point line, free throw, foul,
free-throw line, court, and game clock.


Here are the verbs: shoot, advance, dribble, pass, foul, and rebound. You
also have some additional information about some of the nouns—like the
relative heights of the players at each position, the dimensions of the court,
the total amount of time on a shot clock, and the duration of a game.


Finally, your own commonsense knowledge could come into play as you generate
a few attributes on your own. You know, for example, that the ball has
attributes like volume and diameter.


Using this information, you can create a diagram like the one in Figure
  3.15
. It shows the classes, and provides some attributes, operations, and
  constraints. The diagram also shows responsibilities. You could use this diagram
  as a foundation for further conversations with the coach, to uncover more information.


Figure 3.15Figure
  3.15
An initial class diagram for modeling the game of basketball.




Summary


The rectangle is the UML icon for representing a class. The name, attributes,
operations, and responsibilities of the class fit into areas within the
rectangle. You can use a stereotype to organize lists of attributes and
operations. You elide a class by showing just a subset of its attributes and
operations. This makes a class diagram less busy.


You can show an attribute's type and an initial value, and you can show
the values an operation works on and their types as well. For an operation, this
additional information is called the signature.


To reduce the ambiguity in a class description, you can add constraints. The
UML also allows you to say more about a class by attaching notes to the
rectangle that represents it.


Classes represent the vocabulary of an area of knowledge. Conversations with
a client or an expert in that area reveal nouns that can become classes in a
model and verbs that can become operations. You can use a class diagram as a way
of stimulating the client to talk more about his or her area and reveal
additional knowledge.



Q&A



      

  1.     

    You mention using "commonsense" knowledge to round out
          the class diagram for basketball. That's all well and good, but what
          happens when I have to analyze an area that's new to me—where
          common sense won't necessarily help?


      



      

  1.     

    Typically, you'll be thrust into an area that's new for you.
          Before you meet with a client or with an expert in the field, try to become
          a "subexpert." Prepare for the meeting by reading as much related
          documentation as possible. Ask your interviewee for some papers or manuals
          they might have written. When you've finished reading, you'll
          know some of the fundamentals and you'll be able to ask pointed questions.


      



      

  1.     

    At what point will I want to show an operation's signature?


      



      

  1.     

    Probably after the analysis phase of a development effort, as you get
          into design. The signature is a piece of information that programmers will
          find helpful.


      



      

  1.     

    I've been working for my company for a long time and have in-depth
          knowledge of its business. Do I still have to create a class model of the
          business area the company works in?


      



      

  1.     

    It's a good idea to do that. When you have to model your knowledge,
          you may be surprised at what you don't know.


      



Workshop


To review what you've learned about object-orientation, try your hand at
these quiz questions. The answers appear in Appendix A, "Quiz
Answers."


Quiz



  1. How do you represent a class in the UML?


  2. What information can you show on a class icon?


  3. What is a constraint?


  4. Why would you attach a note to a class icon?



Exercises



      

  1.     

    Here's a brief (and incomplete) description of hockey:


      

  2.   

    A hockey team consists of a center, a goalie, two wings, and two defensemen.
        Each player has a stick, which he uses to advance a puck on the ice. The objective
        is to use the stick to shoot the puck into a goal. Hockey is played on a rink
        with maximum dimensions of 100 feet wide by 200 feet long. The center's
        job is to pass the puck to the wings, who are typically the better shooters
        on the team. The defensemen try to stop the opposing players from getting
        into position to shoot the puck into the goal. The goalie is the last line
        of defense, blocking opposition shots. Each time he stops the puck from getting
        into the goal, he's credited with a "save." Each goal is worth
        one point. A game lasts 60 minutes, divided into three periods of 20 minutes
        each.


      

    Use this information to come up with a diagram like the one in Figure
        3.15
    . If you know more about hockey than I've put in the description,
        add that information to your diagram.


      

  3.     

    If you know more about basketball than I've put in Figure
          3.15
    , add information to that diagram.


      

  4.   

  5.     

    Go back to the conversation between the analyst and the basketball coach.
          Take a look at the coach's responses and find at least three areas
          where you could pursue additional lines of questioning. For example, at
          one point the coach mentions a "three-point line." Further questioning
          would reveal the specifics of that term.


      

  6.   

  7.     

    Here's a preview of what's next: If you had to draw some connections
          among the classes in Figure 3.15, what
          might they look like?


      





Posted by 아름프로




UML Sequence Diagrams



Date: Mar 26, 2004 By Martin Fowler.
Sample Chapter is provided courtesy of Addison Wesley Professional.
Typically, in UML, a sequence diagram captures the behavior of a single scenario. The diagram shows a number of example objects and the messages that are passed between these objects within the use case. This book chapter explains what they're all about, when to use them—plus how to create and delete participants, use loops, conditionals, and the best way to treat synchronous and asynchronous calls.



Interaction diagrams describe how groups of objects collaborate in some behavior. The UML defines several forms of interaction diagram, of which
the most common is the sequence diagram.



Typically, a sequence diagram captures the behavior of a single scenario. The diagram shows a number of example objects and
the messages that are passed between these objects within the use case.



To begin the discussion, I’ll consider a simple scenario. We have an order and are going to invoke a command on it to calculate
its price. To do that, the order needs to look at all the line items on the order and determine their prices, which are based
on the pricing rules of the order line’s products. Having done that for all the line items, the order then needs to compute
an overall discount, which is based on rules tied to the customer.



Figure 4.1 is a sequence diagram that shows one implementation of that scenario. Sequence diagrams show the interaction by showing each
participant with a lifeline that runs vertically down the page and the ordering of messages by reading down the page.



04fig01.gifFigure 4.1. A sequence diagram for centralized control



One of the nice things about a sequence diagram is that I almost don’t have to explain the notation. You can see that an instance
of order sends getQuantity and getProduct messages to the order line. You can also see how we show the order invoking a method on itself and how that method sends
getDiscountInfo to an instance of customer.



The diagram, however, doesn’t show everything very well. The sequence of messages getQuantity, getProduct, getPricingDetails, and calculateBasePrice needs to be done for each order line on the order, while calculateDiscounts is invoked just once. You can’t tell that from this diagram, although I’ll introduce some more notation to handle that later.



Most of the time, you can think of the participants in an interaction diagram as objects, as indeed they were in UML 1. But
in UML 2, their roles are much more complicated, and to explain it all fully is beyond this book. So I use the term participants, a word that isn’t used formally in the UML spec. In UML 1, participants were objects and so their names were underlined,
but in UML 2, they should be shown without the underline, as I’ve done here.



In these diagrams, I’ve named the participants using the style anOrder. This works well most of the time. A fuller syntax is name : Class, where both the name and the class are optional, but you must keep the colon if you use the class. (Figure 4.4, shown on page 58, uses this style.)



Each lifeline has an activation bar that shows when the participant is active in the interaction. This corresponds to one
of the participant’s methods being on the stack. Activation bars are optional in UML, but I find them extremely valuable in
clarifying the behavior. My one exception is when exploring a design during a design session, because they are awkward to
draw on whiteboards.



Naming often is useful to correlate participants on the diagram. The call getProduct is shown returning aProduct, which is the same name, and therefore the same participant, as the aProduct that the getPricingDetails call is sent to. Note that I’ve used a return arrow for only this call; I did that to show the correspondance. Some people
use returns for all calls, but I prefer to use them only where they add information; otherwise, they simply clutter things.
Even in this case, you could probably leave the return out without confusing your reader.



The first message doesn’t have a participant that sent it, as it comes from an undetermined source. It’s called a found message.



For another approach to this scenario, take a look at Figure 4.2. The basic problem is still the same, but the way in which the participants collaborate to implement it is very different.
The Order asks each Order Line to calculate its own Price. The Order Line itself further hands off the calculation to the
Product; note how we show the passing of a parameter. Similarly, to calculate the discount, the Order invokes a method on
the Customer. Because it needs information from the Order to do this, the Customer makes a reentrant call (getBaseValue) to the Order to get the data.



04fig02.gifFigure 4.2. A sequence diagram for distributed control



The first thing to note about these two diagrams is how clearly the sequence diagram indicates the differences in how the
participants interact. This is the great strength of interaction diagrams. They aren’t good at showing details of algorithms,
such as loops and conditional behavior, but they make the calls between participants crystal clear and give a really good
picture about which participants are doing which processing.



The second thing to note is the clear difference in styles between the two interactions. Figure 4.1 is centralized control, with one participant pretty much doing all the processing and other participants there to supply data. Figure 4.2 uses distributed control, in which the processing is split among many participants, each one doing a little bit of the algorithm.



Both styles have their strengths and weaknesses. Most people, particularly those new to objects, are more used to centralized
control. In many ways, it’s simpler, as all the processing is in one place; with distributed control, in contrast, you have
the sensation of chasing around the objects, trying to find the program.



Despite this, object bigots like me strongly prefer distributed control. One of the main goals of good design is to localize
the effects of change. Data and behavior that accesses that data often change together. So putting the data and the behavior
that uses it together in one place is the first rule of object-oriented design.



Furthermore, by distributing control, you create more opportunities for using polymorphism rather than using conditional logic.
If the algorithms for product pricing are different for different types of product, the distributed control mechanism allows
us to use subclasses of product to handle these variations.



In general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for
overriding and variation. This style is very confusing to people used to long procedures; indeed, this change is the heart
of the paradigm shift of object orientation. It’s something that’s very difficult to teach. It seems that the only way to really understand it
is to work in an OO environment with strongly distributed control for a while. Many people then say that they get a sudden
"aha" when the style makes sense. At this point, their brains have been rewired, and they start thinking that decentralized
control is actually easier.




Creating and Deleting Participants



Sequence diagrams show some extra notation for creating and deleting participants (Figure 4.3). To create a participant, you draw the message arrow directly into the participant box. A message name is optional here
if you are using a constructor, but I usually mark it with "new" in any case. If the participant immediately does something
once it’s created, such as the query command, you start an activation right after the participant box.



04fig03.gifFigure 4.3. Creation and deletion of participants



Deletion of a participant is indicated by big X. A message arrow going into the X indicates one participant explicitly deleting
another; an X at the end of a lifeline shows a participant deleting itself.



In a garbage-collected environment, you don’t delete objects directly, but it’s still worth using the X to indicate when an
object is no longer needed and is ready to be collected. It’s also appropriate for close operations, indicating that the object
isn’t usable any more.




A common issue with sequence diagrams is how to show looping and conditional behavior. The first thing to point out is that
this isn’t what sequence diagrams are good at. If you want to show control structures like this, you are better off with an
activity diagram or indeed with code itself. Treat sequence diagrams as a visualization of how objects interact rather than
as a way of modeling control logic.



That said, here’s the notation to use. Both loops and conditionals use interaction frames, which are ways of marking off a piece of a sequence diagram. Figure 4.4 shows a simple algorithm based on the following pseudocode:



04fig04.gifFigure 4.4. Interaction frames



procedure dispatch
foreach (lineitem)
if (product.value > $10K)
careful.dispatch
else
regular.dispatch
end if
end for
if (needsConfirmation) messenger.confirm
end procedure

In general, frames consist of some region of a sequence diagram that is divided into one or more fragments. Each frame has
an operator and each fragment may have a guard. (Table 4.1 lists common operators for interaction frames.) To show a loop, you use the loop operand with a single fragment and put the basis of the iteration in the guard. For conditional logic, you can use an alt operator and put a condition on each fragment. Only the fragment whose guard is true will execute. If you have only one region,
there is an opt operator.



Interaction frames are new in UML 2. As a result, you may see diagrams prepared before UML 2 and that use a different approach;
also, some people don’t like the frames and prefer some of the older conventions. Figure 4.5 shows some of these unofficial tweaks.



04fig05.gifFigure 4.5. Older conventions for control logic



UML 1 used iteration markers and guards. An iteration marker is a * added to the message name. You can add some text in square brackets to indicate the basis of the iteration. Guards are a conditional expression placed in square brackets and indicate that the message is sent only if the guard is true. While
these notations have been dropped from sequence diagrams in UML 2, they are still legal on communication diagrams.



Table 4.1. Common Operators for Interaction Frames












































Operator



Meaning



alt



Alternative multiple fragments; only the one whose condition is true will execute (Figure 4.4).



opt



Optional; the fragment executes only if the supplied condition is true. Equivalent to an alt with only one trace (Figure 4.4).



par



Parallel; each fragment is run in parallel.



loop



Loop; the fragment may execute multiple times, and the guard indicates the basis of iteration (Figure 4.4).



region



Critical region; the fragment can have only one thread executing it at once.



neg



Negative; the fragment shows an invalid interaction.



ref



Reference; refers to an interaction defined on another diagram. The frame is drawn to cover the lifelines involved in the
interaction. You can define parameters and a return value.



sd



Sequence diagram; used to surround an entire sequence diagram, if you wish.




Although iteration markers and guards can help, they do have weaknesses. The guards can’t indicate that a set of guards are
mutually exclusive, such as the two on Figure 4.5. Both notations work only with a single message send and don’t work well when several messages coming out of a single activation
are within the same loop or conditional block.



To get around this last problem, an unofficial convention that’s become popular is to use a pseudomessage, with the loop condition or the guard on a variation of the self-call notation. In Figure 4.5, I’ve shown this without a message arrow; some people include a message arrow, but leaving it out helps reinforce that this
isn’t a real call. Some also like to gray shade the pseudomessage’s activation bar. If you have alterative behavior, you can
show that with an alternative marker between the activations.



Although I find activations very helpful, they don’t add much in the case of the dispatch method, whereby you send a message and nothing else happens within the receiver’s activation. A common convention that I’ve
shown on Figure 4.5 is to drop the activation for those simple calls.



The UML standard has no graphic device to show passing data; instead, it’s shown by parameters in the message name and return
arrows. Data tadpoles have been around in many methods to indicate the movement of data, and many people still like to use them with the UML.



All in all, although various schemes can add notation for conditional logic to sequence diagrams, I don’t find that they work
any better than code or at least pseudocode. In particular, I find the interaction frames very heavy, obscuring the main point
of the diagram, so I prefer pseudomessages.




If you’re exceptionally alert, you’ll have noticed that the arrowheads in the last couple of diagrams are different from the
arrowheads earlier on. That minor difference is quite important in UML 2. In UML 2, filled arrowheads show a synchronous message,
while stick arrowheads show an asynchronous message.



If a caller sends a synchronous message, it must wait until the message is done, such as invoking a subroutine. If a caller sends an asynchronous message, it can continue processing and doesn’t have to wait for a response. You see asynchronous calls in multithreaded applications
and in message-oriented middleware. Asynchrony gives better responsiveness and reduces the temporal coupling but is harder
to debug.



The arrowhead difference is very subtle; indeed, rather too subtle. It’s also a backward-incompatible change introduced in
UML 1.4, before then an asynchronous message was shown with the half-stick arrowhead, as in Figure 4.5.



I think that this arrowhead distinction is too subtle. If you want to highlight asynchronous messages, I would recommend using
the obsolete half-stick arrowhead, which draws the eye much better to an important distinction. If you’re reading a sequence
diagram, beware of making assumptions about synchrony from the arrowheads unless you’re sure that the author is intentionally
making the distinction.




You should use sequence diagrams when you want to look at the behavior of several objects within a single use case. Sequence
diagrams are good at showing collaborations among the objects; they are not so good at precise definition of the behavior.



If you want to look at the behavior of a single object across many use cases, use a state diagram (see Chapter 10). If you want to look at behavior across many use cases or many threads, consider an activity diagram (see Chapter 11).



If you want to explore multiple alternative interactions quickly, you may be better off with CRC cards, as that avoids a lot of drawing and erasing. It’s often handy to have a CRC card session to explore design alternatives and then use sequence diagrams to capture any interactions that you want to refer
to later.



Other useful forms of interaction diagrams are communication diagrams, for showing connections; and timing diagrams, for showing
timing constraints.





CRC Cards



One of the most valuable techniques in coming up with a good OO design is to explore object interactions, because it focuses
on behavior rather than data. CRC (Class-Responsibility-Collaboration) diagrams, invented by Ward Cunningham in the late 1980s, have stood the test of time
as a highly effective way to do this (Figure 4.6). Although they aren’t part of the UML, they are a very popular technique among skilled object designers.



04fig06.gifFigure 4.6. A sample CRC card



To use CRC cards, you and your colleagues gather around a table. Take various scenarios and act them out with the cards, picking them
up in the air when they are active and moving them to suggest how they send messages to each other and pass them around. This
technique is almost impossible to describe in a book yet is easily demonstrated; the best way to learn it is to have someone
who has done it show it to you.



An important part of CRC thinking is identifying responsibilities. A responsibility is a short sentence that summarizes something that an object should do: an action the object performs, some knowledge the
object maintains, or some important decisions the object makes. The idea is that you should be able to take any class and
summarize it with a handful of responsibilities. Doing that can help you think more clearly about the design of your classes.



The second C refers to collaborators: the other classes that this class needs to work with. This gives you some idea of the links between classes—still at a high
level.



One of the chief benefits of CRC cards is that they encourage animated discussion among the developers. When you are working through a use case to see how
classes will implement it, the interaction diagrams in this chapter can be slow to draw. Usually, you need to consider alternatives;
with diagrams, the alternatives can take too long to draw and rub out. With CRC cards, you model the interaction by picking up the cards and moving them around. This allows you to quickly consider alternatives.



As you do this, you form ideas about responsibilities and write them on the cards. Thinking about responsibilities is important,
because it gets you away from the notion of classes as dumb data holders and eases the team members toward understanding the
higher-level behavior of each class. A responsibility may correspond to an operation, to an attribute, or, more likely, to
an undetermined clump of attributes and operations.



A common mistake I see people make is generating long lists of low-level responsibilities. But doing so misses the point.
The responsibilities should easily fit on one card. Ask yourself whether the class should be split or whether the responsibilities
would be better stated by rolling them up into higher-level statements.



Many people stress the importance of role playing, whereby each person on the team plays the role of one or more classes.
I’ve never seen Ward Cunningham do that, and I find that role playing gets in the way.



Books have been written on CRC, but I’ve found that they never really get to the heart of the technique. The original paper on CRC, written with Kent Beck, is [Beck and Cunningham]. To learn more about both CRC cards and responsibilities in design, take a look at [Wirfs-Brock].





Posted by 아름프로


Date: Sep 24, 2004 By Robert Martin.
Sample Chapter is provided courtesy of Prentice Hall PTR.
UML class diagrams allow us to denote the static contents of ? and the relationships between ? classes. In this chapter, Robert Martin explains the basics of UML class diagrams in a practical way.

UML class diagrams allow us to denote the static contents of ? and the relationships between ? classes. In a class diagram
we can show the member variables, and member functions of a class. We can also show whether one class inherits from another,
or whether it holds a reference to another. In short, we can depict all the source code dependencies between classes.



This can be valuable. It can be much easier to evaluate the dependency structure of a system from a diagram than from source
code. Diagrams make certain dependency structures visible. We can see dependency cycles, and determine how best to break them. We can see when abstract classes depend upon concrete classes, and
determine a strategy for rerouting such dependencies.



The Basics



Classes



Figure 3-1 shows the simplest form of class diagram. The class named Dialer is represented as a simple rectangle. This diagram represents nothing more than the code shown to its right.



03fig01.gifFigure
3.1
Class icon.




This is the most common way you will represent a class. The classes on most diagrams don't need any more than their name to
make clear what is going on.



A class icon can be subdivided into compartments. The top compartment is for the name of the class, the second is for the
variables of the class, and the third is for the methods of the class. Figure 3-2 shows these compartments and how they translate into code.



03fig02.gifFigure
3.2
Class icon compartments with corresponding code.




Notice the character in front of the variables and functions in the class icon. A dash (?) denotes private, a hash (#) denotes protected, and a plus (+) denotes public.



The type of a variable, or a function argument is shown after the colon following the variable or argument name. Similarly,
the return value of a function is shown after the colon following the function.



This kind of detail is sometimes useful, but should not be used very often. UML diagrams are not the place to declare variables
and functions. Such declarations are better done in source code. Use these adornments only when they are essential to the
purpose of the diagram.



Association



Associations between classes most often represent instance variables that hold references to other objects. For example, in
Figure 3-3 we see an association between Phone and Button. The direction of the arrow tells us that Phone holds a reference to Button. The name near the arrowhead is the name of the instance variable. The number near the arrowhead tells us how many references
are held.



03fig03.gif
Figure 3.3
Association.




In Figure 3-3 we saw that 15 Button objects were connected to the Phone object. In Figure 3-4, we see what happens when there is no limit. A Phonebook is connected to many PhoneNumber objects. The star means many. In Java this is most commonly implemented with a Vector, a List, or some other container type.



03fig04.gifFigure 3.4




You may have noticed that I avoided using the word "has". I could have said: "A Phonebook has many PhoneNumbers." This was intentional. The common OO verbs HASA and ISA have lead to a number of unfortunate misunderstandings. We'll explore
some of them later in Chapter 6. For now, don't expect me to use the common terms. Rather, I'll use terms that are descriptive of what actually happens in
software, such as: "is connected to."



Inheritance



You have to be very careful with your arrowheads in UML. Figure 3-5 shows why. The little arrowhead pointing at Employee denotes inheritance1. If you draw your arrowheads carelessly, it may be hard to tell whether you mean inheritance or association. To make it clearer,
I often make inheritance relationships vertical and associations horizontal.



03fig05.gif
Figure 3.5
Inheritance.




In UML all arrowheads point in the direction of source code dependency. Since it is the SalariedEmployee class that mentions the name of Employee, the arrowhead points at Employee. So, in UML, inheritance arrows point at the base class.



UML has a special notation for the kind of inheritance used between a Java class and a Java interface. It is shown, in Figure 3-6, as a dashed inheritance arrow2. In the diagrams to come, you'll probably catch me forgetting to dash the arrows that point to interfaces. I suggest you
forget to dash the arrows that you draw on white boards too. Life's too short to be dashing arrows.



03fig06.gifFigure
3.6
Realizes relationship.




Figure 3-7 shows another way to convey the same information. Interfaces can be drawn as little lollipops on the classes that implement
them. We often see this kind of notation in COM designs.



03fig07.gifFigure
3.7
Lollipop interface Indicator.


An Example Class Diagram



Figure 3-8 shows a simple class diagram of part of an ATM system. This diagram is interesting both for what it shows, and for what it
does not show. Note that I have taken pains to mark all the interfaces. I consider it crucial to make sure my readers know
what classes I intend to be interfaces and which I intend to be implemented. For example, the diagram immediately tells you
that WithdrawalTransaction talks to a CashDispenser interface. Clearly some class in the system will have to implement the CashDispenser, but in this diagram we don't care which class it is.



03fig08.gifFigure
3.8
ATM class diagram.




Note that I have not been particularly thorough in documenting the methods of the various UI interfaces. Certainly WithdrawalUI will need more than just the two methods shown there. What about promptForAccount or informCashDispenserEmpty? Putting those methods in the diagram would just clutter it. By providing a representative batch of methods, I've given the
reader the idea. That's all that's really necessary.



Again note the convention of horizontal association and vertical inheritance. This really helps to differentiate these vastly
different kinds of relationships. Without a convention like this it can be hard to tease the meaning out of the tangle.



Notice how I've separated the diagram into three distinct zones. The transactions and their actions are on the left, the various
UI interfaces are all on the right, and the UI implementation is on the bottom. Note also that the connections between the
grouping are minimal and regular. In one case it is three associations, all pointing the same way. In the other case it is
three inheritance relationships all merged into a single line. The grouping, and the way they are connected help the reader
to see the diagram in coherent pieces.



You should be able to see the code as you look at the diagram. Is Listing 3-1 close to what you expected for the implementation of UI?



Example 3-1. UI.java




public class UI implements
WithdrawalUI, DepositUI, TransferUI
{
private Screen itsScreen;
private MessageLog itsMessageLog;

public void displayMessage(String message)
{
itsMessageLog.logMessage(message);
itsScreen.displayMessage(message);
}
}

The Details



There are a vast number of details and adornments that can be added to UML class diagrams. Most of the time these details
and adornments should not be added. But there are times when they can be helpful.



Class stereotypes



Class stereotypes appear between guillemet3 characters, usually above the name of the class. We have seen them before. The ≪interface≫ denotation in Figure 3-8 is a class stereotype. ≪interface≫ is one of two standard stereotypes that can be used by Java programmers. The other is
≪utility≫.



≪interface≫



All the methods of classes marked with this stereotype are abstract. None of the methods can be implemented. Moreover, ≪interface≫
classes can have no instance variables. The only variables they can have are static variables. This corresponds exactly to
Java interfaces. See Figure 3-9.



03fig09.gifFigure
3.9
≪interface≫ class stereotype.




I draw interfaces so often that spelling the whole stereotype out at the white board can be pretty inconvenient. So I often
use the shorthand in the lower part of Figure 3-9 to make the drawing easier. It's not standard UML, but it's much more convenient.



≪utility≫



All the methods and variables of a ≪utility≫ class are static. Booch4 used to call these class utilities. See Figure 3-10.



03fig10.gifFigure
3.10
≪utility≫ class stereotype.




You can make your own stereotypes if you like. I often use stereotypes like ≪persistent≫, ≪C-API≫, ≪struct≫, or ≪function≫.
You just have to make sure that the people who are reading your diagrams know what your stereotype means.



Abstract classes



In UML there are two ways to denote that a class or a method is abstract. You can write the name in italics, or you can use
the {abstract} property. Both options are shown in Figure 3-11.



03fig11.gifFigure
3.11
Abstract classes.




It's a little difficult to write italics at a white board, and the {abstract} property is wordy. So at the white board, if
I need to denote a class or method as abstract, I use the convention shown in Figure 3-12. Again, this isn't standard UML, but at the white board it is a lot more convenient.5



03fig12.gifFigure
3.12
Unofficial denotation of abstract classes.




Properties



Properties, like {abstract} can be added to any class. They represent extra information that's not usually part of a class.
You can create your own properties at any time.



Properties are written in a comma separated list of name?value pairs, like this:



{author=Martin, date=20020429, file=shape.java, private}

The properties in the preceding example are not part of UML. The {abstract} property is the only defined property of UML that
Java programmers would find useful.



If a property does not have a value, it is assumed to take the boolean value true. Thus, {abstract} and {abstract = true} are synonyms.



Properties are written below and to the right of the name of the class, as shown in Figure 3-13.



03fig13.gif Figure 3.13 Properties.



Other than the {abstract} property, I don't know when you'd this useful. Personally, in the many years that I've been writing
UML diagrams, I've never had occasion to use class properties for anything.



Aggregation



Aggregation is a special form of association that connotes a "whole/part" relationship. Figure 3-14 shows how it is drawn and implemented. Notice that the implementation shown in Figure 3-14 is indistinguishable from association. That's a hint.



03fig14.gif
Figure 3.14
Aggregation.




Unfortunately, UML does not provide a strong definition for this relationship. This leads to confusion because various programmers
and analysts adopt their own pet definitions for the relationship. For that reason I don't use the relationship at all, and
I recommend that you avoid it as well. In fact, this relationship has been dropped from UML 2.0.



The one hard rule that UML gives us regarding aggregations is simply this: A whole cannot be its own part. Therefore instances cannot form cycles of aggregations. A single object cannot be an aggregate of itself, two objects cannot be aggregates of
each other, three objects cannot form a ring of aggregation, and so on. See Figure 3-15



03fig15.gifFigure
3.15
Illegal cycles of aggregation between instances.




I don't find this to be a particularly useful definition. How often am I concerned about making sure that instances form a
directed acyclic graph? Not very often. Therefore I find this relationship useless in the kinds of diagrams I draw.



Composition



Composition is a special form of aggregation, as shown in Figure 3-16. Again, notice that the implementation is indistinguishable from association. However, this time the reason is not due to
a lack of definition; this time it's because the relationship does not have a lot of use in a Java program. C++ programmers,
on the other hand, find a lot of use for it.



03fig16.gif Figure 3.16 Composition.



The same rule applies to composition that applied to aggregation. There can be no cycles of instances. An owner cannot be
its own ward. However, UML provides quite a bit more definition.





  • An instance of a ward cannot be owned simultaneously by two owners. The
    object diagram in Figure
    3-17
    is illegal. Note, however, that the corresponding class diagram
    is not illegal. An owner can transfer ownership of a ward to another owner.


    03fig17.gifFigure
    3.17
    Illegal composition.





  • The owner is responsible for the lifetime of the ward. If the owner is
    destroyed, the ward must be destroyed with it. If the owner is copied, the
    ward must be copied with it.





In Java destruction happens behind the scenes by the garbage collector, so there is seldom a need to manage the lifetime of
an object. Deep copies are not unheard of, but the need to show deep copy semantics on a diagram is rare. So, though I have
used composition relationships to describe some Java programs, such use is infrequent.



Figure 3-18 shows how composition is used to denote deep copy. We have a class named Address that holds many Strings. Each string holds one line of the address. Clearly, when you make a copy of the Address, you want the copy to change independently of the original. Thus, we need to make a deep copy. The composition relationship
between the Address and the Strings indicates that copies need to be deep.6



03fig18.gifFigure
3.18
Deep copy is implied by composition.




Multiplicity



Objects can hold arrays or vectors of other objects, or they can hold many of the same kind of objects in separate instance
variables. In UML this can be shown by placing a multiplicity expression on the far end of the association. Multiplicity expressions can be simple numbers, ranges, or a combination of
both. For example, Figure 3-19 shows a BinaryTreeNode, using a multiplicity of 2.



03fig19.gifFigure
3.19
Simple multiplicity.




Here are the allowable forms:
































? Digit.



The exact number of elements.



? * or 0..*



Zero to many.



? 0..1



Zero or one. In Java this is often implemented with a reference that can be null.



? 1..*



One to many.



? 3..5



Three to five.



? 0, 2..5, 9..*



Silly, but legal.




Association stereotypes



Associations can be labeled with stereotypes that change their meaning. Figure 3-20 shows the ones that I use most often.



03fig20.gifFigure
3.20
Association stereotypes.




The ≪create≫ stereotype indicates that the target of the association is created by the source. The implication is that the source creates
the target and then passes it around to other parts of the system. In the example I've shown a typical factory.



The ≪local≫ stereotype is used when the source class creates an instance of the target and holds it in a local variable. The implication
is that the created instance does not survive the member function that creates it. Thus, it is not held by any instance variable
nor passed around the system in any way.



The ≪parameter≫ stereotype shows that the source class gains access to the target instance though the parameter of one of its member functions.
Again, the implication is that the source forgets all about this object once the member function returns. The target is not
saved in an instance variable.



Using dashed dependency arrows, as the diagram shows, is a common and convenient idiom for denoting parameters. I usually
prefer it to using the ≪parameter≫ stereotype.



The ≪delegate≫ stereotype is used when the source class forwards a member function invocation to the target. There are a number of design
patterns where this technique is applied, such as PROXY, DECORATOR, and COMPOSITE7 . Since I use these patterns a lot, I find the notation helpful.



Inner classes



Inner (nested) classes are represented in UML with an association adorned with a crossed circle, as shown in Figure 3-21.



03fig21.gifFigure
3.21
Inner class.




Anonymous inner classes



One of Java's more interesting features is anonymous inner classes. While UML does not have an official stance on these, I
find the notation in Figure 3-22 works well for me. It is concise and descriptive. The anonymous inner class is shown as a nested class that is given the
≪anonymous≫ stereotype, and is also given the name of the interface it implements.



03fig22.gifFigure
3.22
Anonymous inner class.




Association classes



Associations with multiplicity tell us that the source is connected to many instances of the target, but the diagram doesn't
tell us what kind of container class is used. This can be depicted by using an association class, as shown in Figure 3-23.



03fig23.gifFigure
3.23
Association class.




Association classes show how a particular association is implemented. On the diagram they appear as a normal class connected
to the association with a dashed line. As Java programmers we interpret this to mean that the source class really contains
a reference to the association class, which in turn contains references to the target.



Association classes can also be used to indicate special forms of references, such as weak, soft, or phantom references. See
Figure 3-24. On the other hand, this notation is a bit cumbersome and is probably better done with stereotypes as in Figure 3-25.



03fig24.gifFigure
3.24
Association class denoting a weak reference.




03fig25.gifFigure
3.25
Stereotype denoting a weak reference.




Association qualifiers



Association qualifiers are used when the association is implemented through some kind of key or token, instead of with a normal
Java reference. The example in Figure 3-26 shows a LoginServlet associated with an Employee. The association is mediated by a member variable named empid, which contains the database key for the Employee.



03fig26.gifFigure
3.26
Association qualifier.




I find this notation useful in rare situations. Sometimes it's convenient to show that an object is associated to another
through a database or dictionary key. It is important, however, that all the parties reading the diagram know how the qualifier
is used to access the actual object. This is not something that's immediately evident from the notation.

Conclusion



There are lots of widgets, adornments, and whatchamajiggers in UML. There are so many that you can spend a long time becoming
an UML language lawyer, enabling you to do what all lawyers can ? write documents nobody else can understand.



In this chapter I have avoided most of the arcana and byzantine features of UML. Rather I have showed you the parts of UML
that I use. I hope that along with that knowledge I have instilled within you the values of minimalism. Using too little of UML
is almost always better than using too much.

Notes



[Booch1994]: Grady Booch, Object Oriented Analysis and Design with Applications. Redwood City, CA.: Benjamin Cummings, 1994.



[Gamma1995]: Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns. Reading, Mass.: Addison-Wesley, 1995.



Posted by 아름프로





margin-left:22.0pt'>N-ary associations are associations that
connect more than two classes.?Each instance
lang=EN-US>쟯f the association lang=EN-US>쟧s an n-tuple of values from the respective classes.?There are
several characteristics for n-ary association lang=EN-US>s, which are: (i) Multiplicity for ternary associations can be
specified; (ii) The name lang=EN-US>쟯f the association (if any) is shown near the diamond; (iii) Role
adornments can appear on each path lang=EN-US>쟞s with a binary association lang=EN-US>; (iv) The multiplicity lang=EN-US>쟯n a role lang=EN-US>쟲epresents the potential number of instance tuples in the
association when the other N-1 values are fixed.?Indeed, binary association is
a special case that it has its own notation.



0cm;text-indent:0cm'> lang=EN-US>N-ary Association Resource Centric Interface



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image147.png">



style='margin-left:62.35pt;border-collapse:collapse;border:none'>


























Resource


padding:0cm 5.4pt 0cm 5.4pt'>

Name


padding:0cm 5.4pt 0cm 5.4pt'>

Description


padding:0cm 5.4pt 0cm 5.4pt'>

src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image077.png">


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt'>

Association -> Class


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt'>

To create a new Class and connect it
with a bi-directional Association.


padding:0cm 5.4pt 0cm 5.4pt;border:solid windowtext 1.0pt !msorm;border-top:
none !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image082.png">


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

Aggregation -> Class


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

To create a new Class and connect it
with an Aggregation.


padding:0cm 5.4pt 0cm 5.4pt;border:solid windowtext 1.0pt !msorm;border-top:
none !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image083.png">


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

Composition -> Class


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

To create a new Class and connect it
with an Composition.


padding:0cm 5.4pt 0cm 5.4pt'>

src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image045.png">


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt'>

Anchor -> Note


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt'>

To create a Note and connect it with
an Anchor.




margin-left:55.0pt'>Table 5‑8 The
resources of an N-ary Association



0cm;text-indent:0cm'> name="_Toc24191472">Collaboration



 



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image148.png">



 



margin-left:22.0pt'>A collaboration lang=EN-US>쟡escribes how an operation lang=EN-US>쟯r a classifier lang=EN-US>?like a use case lang=EN-US>) is realized by a set of classifiers and associations used in a
specific way. The collaboration defines a set of roles to be played by
instances and links, as well as a set of interactions that define the
communication between the instances when they play those roles.



0cm;text-indent:0cm'> lang=EN-US>Collaboration Resource Centric Interface



 



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image149.jpg">



 



style='margin-left:62.35pt;border-collapse:collapse;border:none'>



















































Resource


padding:0cm 5.4pt 0cm 5.4pt'>

Name


padding:0cm 5.4pt 0cm 5.4pt'>

Description


padding:0cm 5.4pt 0cm 5.4pt;border:solid windowtext 1.0pt !msorm;border-top:
none !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image042.png">


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

Realization -> Package


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

To create a new Package that is a
realization
쟯f the source Collaboration.


padding:0cm 5.4pt 0cm 5.4pt;border:solid windowtext 1.0pt !msorm;border-top:
none !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image058.png">


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

Realization -> Subsystem


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

To create a new Subsystem that is a
realization
쟯f the source Collaboration.


padding:0cm 5.4pt 0cm 5.4pt;border:solid windowtext 1.0pt !msorm;border-top:
none !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image068.png">


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

Realization -> Model


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

To create a new Model that is a
realization
쟯f the source Collaboration.


padding:0cm 5.4pt 0cm 5.4pt'>

src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image150.png">


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt'>

Generalization-> Collaboration


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt'>

To create a Collaboration that is a
generalization
쟯f the source Collaboration.


padding:0cm 5.4pt 0cm 5.4pt'>

src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image151.png">


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt'>

Dependency -> Collaboration


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt'>

To create a Collaboration and
connect it with a Dependency (the source Collaboration depends on the new
Collaboration).


padding:0cm 5.4pt 0cm 5.4pt;border:solid windowtext 1.0pt !msorm;border-top:
none !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image151.png">


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

Usage -> Collaboration


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

To create a Collaboration and
connect it with a Usage Dependency (the source Collaboration depends on the
new Collaboration).


padding:0cm 5.4pt 0cm 5.4pt;border:solid windowtext 1.0pt !msorm;border-top:
none !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image152.png">


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

Binding Dependency ->
Collaboration


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

To create a Collaboration and
connect it with a Binding Dependency (the source Collaboration depends on the
new Collaboration).


padding:0cm 5.4pt 0cm 5.4pt;border:solid windowtext 1.0pt !msorm;border-top:
none !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image153.png">


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

Permission -> Collaboration


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;border-top:
none !msorm;border-left:none !msorm;border-bottom:solid windowtext 1.0pt !msorm;
border-right:solid windowtext 1.0pt !msorm;padding:0cm 5.4pt 0cm 5.4pt !msorm'>

To create a Collaboration and
connect it with a Permission Dependency (the source Collaboration depends on
the new Collaboration).


padding:0cm 5.4pt 0cm 5.4pt'>

src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image045.png">


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt'>

Anchor -> Note


border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt'>

To create a Note and connect it with
an Anchor.




margin-left:55.0pt'>Table 5‑9 The
resources of a Collaboration



0cm;text-indent:0cm'> name="_Toc24191475">Constraint



 



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image154.png">



 



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image155.png">



margin-left:22.0pt'>A constraint lang=EN-US>?/span>is a semantic relationship lang=EN-US>쟞mong model lang=EN-US>쟢lements that specifies conditions and propositions that must be
maintained as true; otherwise, the system lang=EN-US>쟡escribed by the model is invalid (with consequences that are
outside the scope lang=EN-US>쟯f UML). Certain kinds of constraints (such as an association lang=EN-US>젗xor?constraint) are predefined in UML, others may be
user-defined. A user-defined constraint is described in words in a given
language, whose syntax lang=EN-US>쟞nd interpretation is a tool responsibility lang=EN-US>. A constraint represents semantic information attached to a model
element lang=EN-US>, not just to a view lang=EN-US>쟯f it.



0cm;text-indent:0cm'> name="_Toc24191476">Generalization



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image156.png">



margin-left:22.0pt'>Generalization is a relationship lang=EN-US>쟟etween a general element lang=EN-US>쟞nd a more specific kind of that element. It means that the more
specific element can be used whenever the general element appears. This relation
is also known as specialization lang=EN-US>쟯r inheritance lang=EN-US>쟫ink lang=EN-US>.



0cm;text-indent:0cm'> name="_Toc24191477">Usage



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image157.png">



margin-left:22.0pt'>Usage is a dependency lang=EN-US>쟳ituation in which one element lang=EN-US>?the client) requires the presence of another element (the supplier lang=EN-US>) for its correct functioning or implementation lang=EN-US>.



0cm;text-indent:0cm'> name="_Toc24191478">Realization



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image158.png">



margin-left:22.0pt'>Realization is the relationship lang=EN-US>쟟etween a specialization lang=EN-US>쟞nd its implementation lang=EN-US>.?It is an indication of the inheritance lang=EN-US>쟯f behavior lang=EN-US>쟷ithout the inheritance of structure lang=EN-US>.?One classifier lang=EN-US>쟳pecifies a contract lang=EN-US>쟳uch that another classifier guarantees to carry out. Realization
is used in two places: one is between interfaces and the classes that realize
them, and the other is between use case lang=EN-US>s and the collaboration lang=EN-US>쟴hat realize them.



0cm;text-indent:0cm'> name="_Toc24191479">Association



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image159.png">



margin-left:22.0pt'>Association is represented with a line
between classes.?Associations represent structural relationships between
classes and can be named to facilitate model
lang=EN-US>쟵nderstanding.?If two classes are associated you can navigate from
an object lang=EN-US>쟯f one class to an object of the other class.



0cm;text-indent:0cm'> name="_Toc24191481">Aggregation



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image160.png">



margin-left:22.0pt'>Aggregation is a special kind of
association
lang=EN-US>쟧n which one class represents as the larger class that consists of
a smaller class.?It has the meaning of 밾as-a?relationship lang=EN-US>.



0cm;text-indent:0cm'> name="_Toc24191483">Composition



margin-left:22.0pt'>Composition is a strong form of
aggregation association
lang=EN-US>. It has strong ownership lang=EN-US>쟞nd coincident lifetime lang=EN-US>쟯f parts by the whole lang=EN-US>. A part lang=EN-US>쟭ay belong to only one composite. Parts with non-fixed multiplicity lang=EN-US>쟭ay be created after the composite itself. But once created, they
live and die with it (that is, they share lifetimes). Such parts can also be
explicitly removed before the death of the composite.



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image161.png">



0cm;text-indent:0cm'> name="_Toc24191485">Association Class



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image162.png">



margin-left:22.0pt'>Association class is an association lang=EN-US>쟴hat is also a class, and has both association and class
properties.?It can have attributes, operations and even other associations.
It usually helps to further define a many-to-many relationship lang=EN-US>.



0cm;text-indent:0cm'> name="_Toc24191486">Dependency



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image163.png">



margin-left:22.0pt'>The dependency lang=EN-US>쟫ink lang=EN-US>쟧s a semantic relationship lang=EN-US>쟟etween the two elements. It indicates that when a change occurs in
one element lang=EN-US>, there may be a change necessary to the other element.?A
dependency link can include lang=EN-US>쟫abel and stereotype lang=EN-US>쟠an be set.



 



 



0cm;text-indent:0cm'> name="_Toc24191487">Abstraction



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image164.png">



margin-left:22.0pt'>An Abstraction Dependency is a type lang=EN-US>쟯f Dependency with stereotype lang=EN-US>잸bstraction.



0cm;text-indent:0cm'> name="_Toc24191488">Binding



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image165.png">



margin-left:22.0pt'>A Binding Dependency is a type lang=EN-US>쟯f Dependency with stereotype lang=EN-US>잹inding.



0cm;text-indent:0cm'> name="_Toc24191489">Permission



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image166.png">



margin-left:22.0pt'>A Permission Dependency is a type lang=EN-US>쟯f Dependency with stereotype lang=EN-US>쟑ermission.



0cm;text-indent:0cm'> name="_Toc24191490">Containment



margin-left:55.0pt'> src="http://www.visual-paradigm.com/working_with_unified_modeling_language/Working_with_Class_Diagrams_files/image167.png">



margin-left:22.0pt'>Shows a class, package lang=EN-US>쟯r other model lang=EN-US>쟢lement lang=EN-US>쟡eclared within another model element. Such a declared class is not
a structural part lang=EN-US>쟯f the enclosing class but merely has scope lang=EN-US>쟷ithin the namespace lang=EN-US>쟯f the enclosing class, which acts like a package lang=EN-US>쟴oward the inner class.





Posted by 아름프로

Roadmap to

Agile methods and tools



What Is Agile Software Development?


In the late 1990's several methodologies began to get increasing
public attention. Each had a different combination of old ideas, new
ideas, and transmuted old ideas.
But they all emphasized close collaboration
between the programmer team and business experts; face-to-face
communication (as more efficient than written documentation);
frequent delivery of new deployable business value; tight,
self-organizing teams; and ways to craft the code and the
team such that the inevitable requirements churn was not a crisis.



Early 2001 saw a workshop in Snowbird, Utah, USA, where various
originators and practitioners of these methodologies met to figure
out just what it was they had in common. They picked the word "agile"
for an umbrella term and crafted the
Manifesto for Agile Software
Development
, whose most important part was a statement of
shared development values:




We are uncovering better ways of developing
software by doing it and helping others do it.
Through this work we have come to value:




Individuals and interactions over processes and tools

Working software over comprehensive documentation

Customer collaboration over contract negotiation

Responding to change over following a plan




That is, while there is value in the items on
the right, we value the items on the left more.



(See also the attached principles.)



The Manifesto struck a chord, and it led to many new Agile projects
being started. As with any human endeavor, some succeeded and
some failed. But what was striking about the successes was how much
both the business people and the technical people loved their
project. This was the way they wanted software development
done. Successful projects spawned enthusiasts.



The Agile Alliance exists to help more Agile projects succeed and to
help the enthusiasts start more Agile projects. This particular page
is to help people learn more about Agile software development. In
keeping with the Agile emphasis on face-to-face communication, we urge
you to visit a
users group
and talk to your peers about their
experience. But we also provide this Roadmap, which intends to give you a quick
introduction to various agile methods and tools. Click on the links
below to get more info on a certain method or tool. On the following
pages you will find links to pages that contain the specific
information you need.



If you're looking for more information regarding the history of the Agile
Alliance then look at
the articles section
.




Each page contains links to books published on the method. Please use
the supplied link if you intend to order any books. By doing so you
sponsor the Agile Alliance. No hassle for you but a great help for us: href="http://www.amazon.com/exec/obidos/external-search?tag=agilealliance-20&keyword=agile%20methods&mode=books">
General Books on Agile Methods.





Version 2.3 revised on December 16th, 2004





Posted by 아름프로


Mock Objects in Unit Tests
Mock Objects in Unit Tests


by Lu Jian

01/12/2005





The use of mock objects is a widely employed unit testing strategy. It shields external and unnecessary factors from testing and
helps developers focus on a specific function to be tested.



EasyMock is a well-known mock tool that can create a mock object for a
given interface at runtime. The mock object's behavior can be defined prior encountering the test code in the
test case. EasyMock is based on java.lang.reflect.Proxy, which can create dynamic proxy classes/objects
according to given interfaces. But it has an inherent limitation from its use of Proxy: it can create
mock objects only for interfaces.



Mocquer is a similar mock tool, but one that extends the functionality of
EasyMock to support mock object creation for classes as well as interfaces.




Introduction to Mocquer



Mocquer is based on the Dunamis project, which is used to generate dynamic delegation
classes/objects for specific interfaces/classes. For convenience, it follows the class and method naming conventions of EasyMock, but uses a
different approach internally.



MockControl is the main class in the Mocquer project. It is used to control the the mock object life cycle
and behavior definition. There are four kinds methods in this class.



  • Life Cycle Control Methods

    public void replay();
    public void verify();
    public void reset();


    The mock object has three states in its life cycle: preparing, working, and
    checking. Figure 1 shows the mock object life cycle.



    Mock Object Life Cycle

    Figure 1. Mock object life cycle


    Initially, the mock object is in the preparing state. The mock object's behavior can be defined in this state.
    replay() changes the mock object's state to the working state. All method invocations on the
    mock object in this state will follow the behavior defined in the preparing state. After verify()
    is called, the mock object is in the checking state. MockControl will compare the mock object's predefined behavior
    and actual behavior to see whether they match. The match rule depends on which kind of MockControl is
    used; this will be explained in a moment. The developer can use replay() to reuse
    the predefined behavior if needed. Call reset(), in any state, to clear the history state and
    change to the initial preparing state.



  • Factory Methods

    public static MockControl createNiceControl(...);
    public static MockControl createControl(...);
    public static MockControl createStrictControl(...);


    Mocquer provides three kinds of MockControls: Nice, Normal, and Strict.
    The developer can choose an appropriate MockControl in his or her test case, according to what is to be tested (the test point) and how the test
    will be carried out (the test strategy).
    The Nice MockControl is the loosest. It does not care about the order of method invocation on the mock object, or about unexpected method invocations, which just return a default value (that depends on the method's return value).
    The Normal MockControl is stricter than the Nice MockControl, as an unexpected method invocation on the mock object will lead to
    an AssertionFailedError. The Strict MockControl is, naturally, the strictest. If the order of method invocation on the
    mock object in the working state is different than that in the preparing state, an AssertionFailedError will be
    thrown.
    The table below shows the differences between these three kinds of MockControl.






















      Nice Normal Strict
    Unexpected Order Doesn't care Doesn't care AssertionFailedError
    Unexpected Method Default value AssertionFailedError AssertionFailedError

    There are two versions for each factory method.





    public static MockControl createXXXControl(Class clazz);
    public static MockControl createXXXControl(Class clazz,
    Class[] argTypes, Object[] args);



    If the class to be mocked is an interface or it has a public/protected default constructor, the first version is
    enough. Otherwise, the second version factory method is used to specify the signature and provide arguments to the desired constructor. For example, assuming ClassWithNoDefaultConstructor is a class without a default
    constructor:




    public class ClassWithNoDefaultConstructor {
    public ClassWithNoDefaultConstructor(int i) {
    ...
    }
    ...
    }


    The MockControl can be obtained through:




    MockControl control = MockControl.createControl(
    ClassWithNoDefaultConstructor.class,
    new Class[]{Integer.TYPE},
    new Object[]{new Integer(0)});


  • Mock object getter method

    public Object getMock();


    Each MockControl contains a reference to the generated mock object. The developer can use this method to
    get the mock object and cast it to the real type.




    //get mock control
    MockControl control = MockControl.createControl(Foo.class);
    //Get the mock object from mock control
    Foo foo = (Foo) control.getMock();



  • Behavior definition methods

    public void setReturnValue(... value);
    public void setThrowable(Throwable throwable);
    public void setVoidCallable();
    public void setDefaultReturnValue(... value);
    public void setDefaultThrowable(Throwable throwable);
    public void setDefaultVoidCallable();
    public void setMatcher(ArgumentsMatcher matcher);
    public void setDefaultMatcher(ArgumentsMatcher matcher);


    MockControl allows the developer to define the mock object's behavior per each method invocation on it. When in
    the preparing state, the developer can call one of the mock object's methods first to specify which method invocation's
    behavior is to be defined. Then, the developer can use one of the behavior definition methods to specify the behavior. For example,
    take the following Foo class:




    //Foo.java
    public class Foo {
    public void dummy() throw ParseException {
    ...
    }
    public String bar(int i) {
    ...
    }
    public boolean isSame(String[] strs) {
    ...
    }
    public void add(StringBuffer sb, String s) {
    ...
    }
    }


    The behavior of the mock object can be defined as in the following:


    //get mock control
    MockControl control = MockControl.createControl(Foo.class);
    //get mock object
    Foo foo = (Foo)control.getMock();
    //begin behavior definition

    //specify which method invocation's behavior
    //to be defined.
    foo.bar(10);
    //define the behavior -- return "ok" when the
    //argument is 10
    control.setReturnValue("ok");
    ...

    //end behavior definition
    control.replay();
    ...


    Most of the more than 50 methods in MockControl are behavior definition methods. They can
    be grouped into following categories.




    • setReturnValue()

      These methods are used to specify that the last method invocation should return a value as the parameter. There
      are seven versions of setReturnValue(), each of which takes a primitive type as its parameter, such as
      setReturnValue(int i) or setReturnValue(float f). setReturnValue(Object obj) is used for a method that takes an object instead of a primitive. If the given value does not match the method's return type, an AssertionFailedError will be
      thrown.



      It is also possible to add the number of expected invocations into the behavior definition. This is called the invocation times limitation.




      MockControl control = ...
      Foo foo = (Foo)control.getMock();
      ...
      foo.bar(10);
      //define the behavior -- return "ok" when the
      //argument is 10. And this method is expected
      //to be called just once.
      setReturnValue("ok", 1);
      ...


      The code segment above specifies that the method invocation, bar(10), can only occur once. How about
      providing a range?




      ...
      foo.bar(10);
      //define the behavior -- return "ok" when the
      //argument is 10. And this method is expected
      //to be called at least once and at most 3
      //times.
      setReturnValue("ok", 1, 3);
      ...


      Now bar(10) is limited to be called at least once and at most, three times. More appealingly, a Range
      can be given to specify the limitation.




      ...
      foo.bar(10);
      //define the behavior -- return "ok" when the
      //argument is 10. And this method is expected
      //to be called at least once.
      setReturnValue("ok", Range.ONE_OR_MORE);
      ...


      Range.ONE_OR_MORE is a pre-defined Range instance, which means the method should be called at least once.
      If there is no invocation-count limitation specified in setReturnValue(), such as setReturnValue("Hello"),
      it will use Range.ONE_OR_MORE as its default invocation-count limitation.
      There are another two predefined Range instances: Range.ONE (exactly once) and
      Range.ZERO_OR_MORE (there's no limit on how many times you can call it).



      There is also a special set return value method: setDefaultReturnValue(). It defines the return value
      of the method invocation despite the method parameter values. The invocation times limitation is Range.ONE_OR_MORE.
      This is known as the method parameter values insensitive feature.




      ...
      foo.bar(10);
      //define the behavior -- return "ok" when calling
      //bar(int) despite the argument value.
      setDefaultReturnValue("ok");
      ...



    • setThrowable

      setThrowable(Throwable throwable) is used to define the method invocation's exception throwing behavior. If the given throwable does not match the exception declaration of the method, an
      AssertionFailedError will be thrown. The invocation times limitation and method parameter values
      insensitive features can also be applied.




      ...
      try {
      foo.dummy();
      } catch (Exception e) {
      //skip
      }
      //define the behavior -- throw ParseException
      //when call dummy(). And this method is expected
      //to be called exactly once.
      control.setThrowable(new ParseException("", 0), 1);
      ...



    • setVoidCallable()

      setVoidCallable() is used for a method that has a void return type. The invocation
      times limitation and method parameter values insensitive features can also be applied.




      ...
      try {
      foo.dummy();
      } catch (Exception e) {
      //skip
      }
      //define the behavior -- no return value
      //when calling dummy(). And this method is expected
      //to be called at least once.
      control.setVoidCallable();
      ...


    • Set ArgumentsMatcher

      In the working state, the MockControl will search the predefined behavior when any method invocation has happened
      on the mock object. There are three factors in the search criteria: method signature, parameter value, and invocation
      times limitation. The first and third factors are fixed. The second factor can be skipped by the parameter values
      insensitive feature described above. More flexibly, it is also possible to customize the parameter value match rule.
      setMatcher() can be used in the preparing state with a customized ArgumentsMatcher.




      public interface ArgumentsMatcher {
      public boolean matches(Object[] expected,
      Object[] actual);
      }

      The only method in ArgumentsMatcher, matches(), takes two arguments. One is the expected
      parameter values array (null, if the parameter values insensitive feature applied). The other is the actual parameter
      values array. A true return value means that the parameter values match.




      ...
      foo.isSame(null);
      //set the argument match rule -- always match
      //no matter what parameter is given
      control.setMatcher(MockControl.ALWAYS_MATCHER);
      //define the behavior -- return true when call
      //isSame(). And this method is expected
      //to be called at least once.
      control.setReturnValue(true, 1);
      ...


      There are three predefined ArgumentsMatcher instances in MockControl.
      MockControl.ALWAYS_MATCHER always returns true when matching, no matter what parameter
      values are given. MockControl.EQUALS_MATCHER calls equals() on each element
      in the parameter value array. MockControl.ARRAY_MATCHER is almost the same as
      MockControl.EQUALS_MATCHER, except that it calls Arrays.equals() instead of
      equals() when the element in the parameter value array is an array type. Of course, the developer
      can implement his or her own ArgumentsMatcher.



      A side effect of a customized ArgumentsMatcher is that it defines the method invocation's out
      parameter value.




      ...
      //just to demonstrate the function
      //of out parameter value definition
      foo.add(new String[]{null, null});
      //set the argument match rule -- always
      //match no matter what parameter given.
      //Also defined the value of out param.
      control.setMatcher(new ArgumentsMatcher() {
      public boolean matches(Object[] expected,
      Object[] actual) {
      ((StringBuffer)actual[0])
      .append(actual[1]);
      return true;
      }
      });
      //define the behavior of add().
      //This method is expected to be called at
      //least once.
      control.setVoidCallable(true, 1);
      ...


      setDefaultMatcher() sets the MockControl's default ArgumentsMatcher instance. If no
      specific ArgumentsMatcher is given, the default ArgumentsMatcher will be used. This
      method should be called before any method invocation behavior definition. Otherwise, an
      AssertionFailedError will be thrown.


      //get mock control
      MockControl control = ...;
      //get mock object
      Foo foo = (Foo)control.getMock();

      //set default ArgumentsMatcher
      control.setDefaultMatcher(
      MockControl.ALWAYS_MATCHER);
      //begin behavior definition
      foo.bar(10);
      control.setReturnValue("ok");
      ...


      If setDefaultMatcher() is not used,
      MockControl.ARRAY_MATCHER
      is the system default
      ArgumentsMatcher.























JUnit Pocket Guide

Related Reading


JUnit Pocket Guide


By Kent잹eck
































An Example


Below is an example that demonstrates Mocquer's usage in unit testing.


Suppose there is a class named FTPConnector.




package org.jingle.mocquer.sample;

import java.io.IOException;
import java.net.SocketException;

import org.apache.commons.net.ftp.FTPClient;

public class FTPConnector {
//ftp server host name
String hostName;
//ftp server port number
int port;
//user name
String user;
//password
String pass;

public FTPConnector(String hostName,
int port,
String user,
String pass) {
this.hostName = hostName;
this.port = port;
this.user = user;
this.pass = pass;
}

/**
* Connect to the ftp server.
* The max retry times is 3.
* @return true if succeed
*/
public boolean connect() {
boolean ret = false;
FTPClient ftp = getFTPClient();
int times = 1;
while ((times <= 3) && !ret) {
try {
ftp.connect(hostName, port);
ret = ftp.login(user, pass);
} catch (SocketException e) {
} catch (IOException e) {
} finally {
times++;
}
}
return ret;
}

/**
* get the FTPClient instance
* It seems that this method is a nonsense
* at first glance. Actually, this method
* is very important for unit test using
* mock technology.
* @return FTPClient instance
*/
protected FTPClient getFTPClient() {
return new FTPClient();
}
}


The connect() method can try to connect to an FTP server and log in. If it fails, it can retry up to three times.
If the operation succeeds, it returns true. Otherwise, it returns false. The class uses org.apache.commons.net.FTPClient
to make a real connection. There is a protected method, getFTPClient(), in this class that looks like nonsense at first glance. Actually, this method is very important for unit testing using mock technology. I will explain
that later.



A JUnit test case, FTPConnectorTest, is provided to test the connect() method logic.
Because we want to isolate the unit test environment from any other factors such as an external FTP server, we use
Mocquer to mock the FTPClient.




package org.jingle.mocquer.sample;

import java.io.IOException;

import org.apache.commons.net.ftp.FTPClient;
import org.jingle.mocquer.MockControl;

import junit.framework.TestCase;

public class FTPConnectorTest extends TestCase {

/*
* @see TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
}

/*
* @see TestCase#tearDown()
*/
protected void tearDown() throws Exception {
super.tearDown();
}

/**
* test FTPConnector.connect()
*/
public final void testConnect() {
//get strict mock control
MockControl control =
MockControl.createStrictControl(
FTPClient.class);
//get mock object
//why final? try to remove it
final FTPClient ftp =
(FTPClient)control.getMock();

//Test point 1
//begin behavior definition
try {
//specify the method invocation
ftp.connect("202.96.69.8", 7010);
//specify the behavior
//throw IOException when call
//connect() with parameters
//"202.96.69.8" and 7010. This method
//should be called exactly three times
control.setThrowable(
new IOException(), 3);
//change to working state
control.replay();
} catch (Exception e) {
fail("Unexpected exception: " + e);
}

//prepare the instance
//the overridden method is the bridge to
//introduce the mock object.
FTPConnector inst = new FTPConnector(
"202.96.69.8",
7010,
"user",
"pass") {
protected FTPClient getFTPClient() {
//do you understand why declare
//the ftp variable as final now?
return ftp;
}
};
//in this case, the connect() should
//return false
assertFalse(inst.connect());

//change to checking state
control.verify();

//Test point 2
try {
//return to preparing state first
control.reset();
//behavior definition
ftp.connect("202.96.69.8", 7010);
control.setThrowable(
new IOException(), 2);
ftp.connect("202.96.69.8", 7010);
control.setVoidCallable(1);
ftp.login("user", "pass");
control.setReturnValue(true, 1);
control.replay();
} catch (Exception e) {
fail("Unexpected exception: " + e);
}

//in this case, the connect() should
//return true
assertTrue(inst.connect());

//verify again
control.verify();
}
}

A strict MockObject is created. The mock object variable declaration has a final modifier because the variable
will be used in the inner anonymous class. Otherwise, a compilation error will be reported.




There are two test points in the test method. The first test point is when FTPClient.connect() always throws an
exception, meaning FTPConnector.connect() will return false as result.




try {
ftp.connect("202.96.69.8", 7010);
control.setThrowable(new IOException(), 3);
control.replay();
} catch (Exception e) {
fail("Unexpected exception: " + e);
}


The MockControl specifies that, when calling connect() on the mock object with the parameters 202.96.96.8 as the host IP and
7010 as the port number, an IOException will be thrown. This method invocation is expected to be called exactly
three times. After the behavior definition, replay() changes the mock object to the working state. The try/catch
block here is to follow the declaration of FTPClient.connect(), which has an IOException defined
in its throw clause.




FTPConnector inst = new FTPConnector("202.96.69.8",
7010,
"user",
"pass") {
protected FTPClient getFTPClient() {
return ftp;
}
};


The code above creates a FTPConnector instance with its getFTPClient() overridden. It is a bridge to
introduce the created mock object into the target to be tested.




assertFalse(inst.connect());


The expected result of connect() should be false on this test point.




control.verify();


Finally, change the mock object to the checking state.




The second test point is when FTPClient.connect() throws exceptions two times and succeeds on the third time,
and FTPClient.login() also succeeds, meaning FTPConnector.connect() will return true as result.




This test point follows the procedure of previous test point, except that the MockObject should change to the preparing state first,
using reset().




Conclusion



Mock technology isolates the target to be tested from other external factors. Integrating mock technology
into the JUnit framework makes the unit test much simpler and neater. EasyMock is a good mock tool that can
create a mock object for a specified interface. With the help of Dunamis, Mocquer extends the function of EasyMock.
It can create mock objects not only for interfaces, but also classes. This article gave a brief introduction to
Mocquer's usage in unit testing. For more detailed information, please refer to the references below.



References





Lu Jian
is a senior Java architect/developer with four years of Java development experience.




Posted by 아름프로
Extreme Programming

Customer Team Member – Teams have someone (or a group of people) representing the interests of the customer. They decide what is in the product and what is not in the product.

Planning Game - XP is an iterative development process. In the planning game, the customer and the programmers determine the scope of the next release. Programmers estimating the feature costs. Customers select features and package the development of those features into small iterations (typically 2 weeks). Iterations are combined into meaningful end user releases.

User Story – A User Story represents a feature of the system. The customer writes the story on a note card. Stories are small. The estimate to complete a story is limited to no greater than what one person could complete within a single iteration.

Small Releases – Programmers build the system in small releases defined. An iteration is typically two weeks. A release is a group of iterations that provide valuable features to the users of the system.

Acceptance Testing – The customer writes acceptance tests. The tests demonstrate that the story is complete. The programmers and the customer automate acceptance tests. Programmers run the tests multiple times per day.

Open Workspace – To facilitate communications the team works in an open workspace with all the people and equipment easily accessible.

Test Driven Design – Programmers write software in very small verifiable steps. First, we write a small test. Then we write enough code to satisfy the test. Then another test is written, and so on.

Metaphor – The system metaphor provides an idea or a model for the system. It provides a context for naming things in the software, making the software communicate to the programmers.

Simple Design – The design in XP is kept as simple as possible for the current set of implemented stories. Programmers don’t build frameworks and infrastructure for the features that might be coming.

Refactoring – As programmers add new features to the project, the design may start to get messy. If this continues, the design will deteriorate. Refactoring is the process of keeping the design clean incrementally.

Continuous Integration – Programmers integrate and test the software many times a day. Big code branches and merges are avoided.

Collective Ownership – The team owns the code. Programmer pairs modify any piece of code they need to. Extensive unit tests help protect the team from coding mistakes.

Coding Standards – The code needs to have a common style to facilitate communication between programmers. The team owns the code; the team owns the coding style.

Pair Programming – Two programmers collaborate to solve one problem. Programming is not a spectator sport.

Sustainable Pace –The team needs to stay fresh to effectively produce software. One way to make sure the team makes many mistakes is to have them work a lot of overtime.

출처 : http://www.objectmentor.com/processImprovement/index
Posted by 아름프로
tools such as Ant or Maven are the foundation for continuous integration. You can build on that foundation by using a dedicated continuous integration tool like CruiseControl, Gump or AntHill.

ant
http://ant.apache.org

maven
http://maven.apache.org

CruiseControl
http://cruisecontrol.sourceforge.net/

Gump
http://jakarta.apache.org/gump/

AntHill
http://www.urbancode.com/projects/anthill/
Posted by 아름프로
== client side ==

junit.jar: obviously this is needed for the JUnit Test Runner and because the Cactus XXXTestCase classes extend the JUnit org.junit.framework.TestCase class.

cactus.jar: well, this is the Cactus jar containing all Cactus classes,

your test classes: these are your test classes that extend the Cactus XXXTestCase classes,

servlet.jar or j2ee.jar: these are the Servlet API / J2EE API interfaces. This is needed on the client side classpath because your test cases extend one or several of XXXTestCase which use class variables that are Servlet / J2EE objects (HttpSevletRequest, PageContext, ...). You can get this jar either from your servlet engine or from the Sun Web Site

httpclient.jar: needed for Cactus Cookie handling.

commons-logging.jar: Cactus uses the Jakarta Commons Logging facade framework to provide seamless Cactus logging using any existing Logging framework (Log4j, LogKit, JDK 1.4 Logging, etc). It is also needed for Commons HttpClient.

logging framework jar(optional): The logging framework to use (Log4j jar, LogKit jar, etc). It is optional as it is only needed for internal Cactus logging and in addition, the Commons Logging framework provides a simple logger that logs on the console.

httpunit.jar, Tidy.jar and xerces.jar (optional): only needed if you wish to use HttpUnit in your endXXX() methods (see the HttpUnit Howto tutorial). The 3 jars mentioned above are part of the HttpUnit distribution.

aspectjrt.jar: AspectJ runtime jar.


If you have the habit of using class variables for the classes to test (as opposed to declaring them within the testXXX() method), you'll also need to put your classes under test in the client side classpath.

If you are using Log4J as the logging framework, you will also need to put a log4j.properties Log4j configuration file in your client side classpath (See the Config Howto tutorial).



---------------------------------------------------------------------

== server side ==

WEB-INF/lib/cactus.jar: the Cactus main jar,

WEB-INF/lib/junit.jar: this is needed because the Cactus XXXTestCase extends the JUnit org.junit.framework.TestCase class.

WEB-INF/classes/ : obviously as their testXXX() methods will get executed in the container.

WEB-INF/classes/ : will be called by your test classes.

aspectjrt.jar: AspectJ runtime jar.

WEB-INF/lib/commons-logging.jar: Cactus uses the Jakarta Commons Logging facade framework to provide seamless Cactus logging using any existing Logging framework (Log4j, LogKit, JDK 1.4 Logging, etc). It is also needed for Commons HttpClient.

WEB-INF/lib/logging framework jar (optional): The logging framework to use (Log4j jar, LogKit jar, etc). It is optional as it is only needed for internal Cactus logging and in addition, the Commons Logging framework provides a simple logger that logs on the console.


If you have several webapps that use cactus you can put all Cactus jars in a place loaded by your container System classloader (provided your container correctly sets the Context classloader). The location is container-dependent; for example for Tomcat 4.x, you can put the jars in TOMCAT_HOME/common/lib.

If you are using Log4J as the logging framework, you will also need to put a log4j.properties Log4j configuration file in your server side classpath (usually in WEB-INF/classes).

-------------------------------------------------------------------------

Posted by 아름프로
# 이상적인 모양
- Mock Object : 도메인 로직 검사
- Cactus : 통합 테스팅
- HttpUnit : 기능 테스트
- JXUnit : Building Suites of Test Data with XML
- DBUnit : dataset

1. Mock Object
http://www.mockobjects.com

2. Cactus
http://jakarta.apache.org/cactus

3. HttpUnit
http://httpunit.sourceforge.net

4. JXUnit
http://jxunit.sourceforge.net/

5. DBUnit
http://dbunit.sourceforge.net/
Posted by 아름프로
Struts Applications

The Struts/SourceForge site hosts sample applications and related components based on the Apache Struts Web application framework.

http://struts.sourceforge.net/

==============================================
Posted by 아름프로
Struts Menu

Web menuing framework for JSP and Struts based applications. Menus can be defined in an XML file and displayed through the use of JSP tags. Support for dynamic javascript menus is included.

http://struts-menu.sourceforge.net/

====================================
Posted by 아름프로
ProGuard

ProGuard is a free Java class file shrinker and obfuscator. It can detect and remove unused classes, fields, methods, and attributes. It can then rename the remaining classes, fields, and methods using short meaningless names. The resulting jars are smaller and harder to reverse-engineer.

http://proguard.sourceforge.net/

=============================================
Posted by 아름프로
FreeMind

A mind mapper, and at the same time an easy-to-operate hierarchical editor with strong emphasis on folding. These two are not really two different things, just two different descriptions of a single application. Often used for knowledge and content mgmt.

http://freemind.sourceforge.net/

=======================================
Posted by 아름프로
JGraph Diagram Component

JGraph is the most powerful, lightweight, feature-rich, and thoroughly documented open-source graph component available for Java. It is accompanied by JGraphpad, the first free diagram editor for Java that offers XML, Drag and Drop and much more!

http://www.jgraph.com/

=========================================
Posted by 아름프로
JasperReports

JasperReports is a powerful report-generating tool that has the ability to deliver rich content onto the screen, to the printer or into PDF, HTML, XLS, CSV and XML files.

http://jasperreports.sourceforge.net/

===============================================
iReport-Designer for JasperReports

iReport is a visual reporting tool based on JasperReports written in 100% pure java. You can manage charts, images, subreports,... Data can be retrived using JDBC, TableModels, JavaBeans, XML,...It supports output in PDF,XML,XLS,CSV,HTML,Java2D,...

http://ireport.sourceforge.net

===============================================
Posted by 아름프로
Hibernate
Hibernate - Relational Persistence for Idiomatic Java

http://www.hibernate.org/

===========================================
HSQL Database Engine

HSQLDB is a relational database engine written in Java, with a JDBC driver, supporting a subset of ANSI-92 SQL. It offers a small (about 100k), fast database engine which offers both in memory and disk based tables. This product includes Hypersonic SQL

http://hsqldb.sourceforge.net/
===========================================
jTDS - The JDBC driver for MS SQL Server

Open source pure Java JDBC 2.0 driver for the Microsoft SQL Server series (6.5, 7.0 and 2000). jTDS is the only free JDBC driver for MSSQL still under active development. For more information see the project's home page

http://jtds.sourceforge.net/

Posted by 아름프로
jBpm.org - java Business Process Mgmt

jBpm is a WorkFlow Management System. Business processes must be expressed in process archives in a simple and powerfull language. Users or systems perform single steps of the process. jBpm maintains the state, logs and performs all automated actions.

http://jbpm.org/

===============================================
Posted by 아름프로
httpunit

a Java library for the automatic stimulation and testing of web applications

http://httpunit.sourceforge.net/

============================================
StrutsTestCase for JUnit

StrutsTestCase for JUnit is an extension of the standard JUnit TestCase class that provides facilities for testing code based on the Struts framework. StrutsTestCase provides both a Mock Object approach and a Cactus approach to actually run the Struts ActionServlet, allowing you to test your Struts code with or without a running servlet engine. Because StrutsTestCase uses the ActionServlet controller to test your code, you can test not only the implementation of your Action objects, but also your mappings, form beans, and forwards declarations. And because StrutsTestCase already provides validation methods, it's quick and easy to write unit test cases.

http://strutstestcase.sourceforge.net/

============================================
Jameleon

Jameleon - An Automated Testing Tool

http://jameleon.sourceforge.net/index.html

============================================
Posted by 아름프로
JFreeChart

JFreeChart is a free Java class library for generating charts, including:
- pie charts;
- bar charts (regular and stacked, with an optional 3D effect);
- line and area charts;
- scatter plots and bubble charts;
- time series, high/low/open/close charts and candle stick charts;
- combination charts;
- Pareto charts;
- Gantt charts;
- wind plots, meter charts and symbol charts;
- wafer map charts;

http://www.jfree.org/jfreechart/index.html

==============================================
Posted by 아름프로
PMD scans Java source code and looks for potential problems like:

Unused local variables
Empty catch blocks
Unused parameters
Empty 'if' statements
Duplicate import statements
Unused private methods
Classes which could be Singletons
Short/long variable and method names
PMD has plugins for JEdit, JBuilder, NetBeans/Sun ONE Studio, IntelliJ IDEA, TextPad, Maven, Ant, Eclipse, Gel, and Emacs.

http://pmd.sourceforge.net

===========================================
Eclipse Checkstyle Plug-in

The Eclipse Checkstyle plug-in integrates the Checkstyle Java code auditor into the Eclipse IDE. The plug-in provides real-time feedback to the user about violations of rules that check for coding style and possible error prone code constructs

http://eclipse-cs.sourceforge.net/

===========================================

===========================================
Posted by 아름프로
Project planning and tracking and managing tool

==============================================
NetOffice

Online project management with team collaboration, user management, multiple access levels, tasks, projects, and time tracking, task change history, files approval tracking, notes, client project sites, CRM, Gantt graphs... (a phpCollab fork)

http://netoffice.sourceforge.net/index.php
==============================================
Double Choco Latte

Double Choco Latte is a project to create a solution for managing some IT departments including software development and call center activity. It has a web interface and will also have a stand-alone Java client.

http://dcl.sourceforge.net/
==============================================
XPlanner

XPlanner is a web-based project planning and tracking tool for eXtreme Programming (XP) teams. XPlanner is implemented using Java, JSP, and Struts, and MySQL (user contributed support for other databases).

http://www.xplanner.org/
==============================================
Mantis

Mantis is an easily deployable, web based bugtracker to aid product bug tracking. It requires PHP and MySQL and a web server. It is simpler than Bugzilla and easily editable. Check out the online Demo.

http://mantisbt.sourceforge.net/
==============================================
jagzilla

A Java web services/hibernate based interface for bugzilla. Java based apps sould access extremly easy bugzilla with jagzilla. Two methods are supported: JDBC with hibernate for on site use, and Web services for more open usage.

http://jagzilla.sourceforge.net/

==============================================
Posted by 아름프로
Refactoring Workbook - Source Code



***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로
Refactoring Workbook



***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로
Refactoring
What is Refactoring? It is improving the design of your code without adding new behavior. Why would you want to do that? To boost your productivity. How does it help do that? By helping you produce smaller, simpler, better communicating code. To learn more, read Martin Fowler's classic: Refactoring: Improving the Design of Existing Code.


Refactoring To Patterns
Download the latest draft (Adobe Acrobat, under 750k)
Last updated: February 11, 2003
Refactoring to Patterns is a growing body of work that includes neary 2 dozen refactorings. As I continue to improve and extend the book, I welcome your feedback and suggestions. I'll be presenting tutorials on this subject at upcoming conferences as well as in The Design Patterns Workshop. -- Joshua Kerievsky




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로


Errata for Refactoring



Here are the current known errors in the Refactoring book.



Many thanks to Mike Anderson, Alex Aptekman, Beth Egan Bradtke, Greg Cohoon, George Cowan, John Dale, Dion Dock, Jutta Eckstein, Paul Haahr, John Hollister, Heinz Kabutz, Bernd Kahlbrandt, Bart Koestner, Jung-joon Kim, Mark Kinzie, Hamish Lawson, Hwijae Lee, Jaeik Lee, Marc Lepage, Ron Lusk, Rory Molinari, Anthon van der Neut, Orjan Petersson, Jon Reid, Oliver Rode, Phil Rodgers, Gavin Scott, Patricia Shanahan, Pradyumn Sharma, Joel Smith, Ellen Spertus, Dawie Strauss, Frank Tip, Madhavi Tolety, Bill Wake and Hirohide Yazaki  for spotting and telling me about these errors




Errors in the eighth (and later) printing

Page 2:
        In the first paragraph "and identifies the type movie" should read "and identifies the type of movie".

Page 12:
        

I've been asked for more information about the double to int rounding. It happens when you have a compound assignment. In other words
        


        
        int foo=1;
        foo += 1.5;
        

        

compiles, as it is equivalent to


        
        int foo = 1;
        foo = (int) (foo + 1.5);
        

        

I haven't looked into the rationale behind this. (see Java Language Specification, section 15.26.2)
        


Page 40:
In the code examples on pages 40 and 41 the references to the field _name should instead be _title

Page 98:
        The method testReadAtEnd is incorrect. I looked at my source files and found the method there to say


        public void testReadAtEnd() throws IOException {
                int ch = -1234;
                for        (int i = 0; i < 141; i++)
                        ch = _input.read();
                assertEquals("read at end", -1, _input.read());
        }
        

        Another reason to be glad that these days I'm auto-inserting source code!

Page 115:
In the third line, "rerun" should be "return"

Page 120:
        In the solution statement the phrase "Replace all references to the temp with the expression" should be replaced with "Replace all references to the temp with the new method"

Page 121:
        This was an incorrect fix to an earlier error. In the last line of the mechanics the refactoring 'Replace Temp with Inline Temp' should read 'Inline Temp'. The same problem occurs on page 122.

Page 153:
        In the second para, third line "As discussed in Lea by section..." should read "As discussed in Lea in section...."

Page 176:
        In the second para, (a step in the mechanics) "change the getting method" should read "change the setting method"

Page 185:
        In the second paragraph "biwise xor" shoudl read "bitwise xor"

Page 222:
        At the bottom of the page I make the method getCode private. I obviously can't do that while any clients of BloodGroup are using the method.

Page 225:
        The first mention of the create method is missing the static keyword.

Page 240:
        On this page and on later pages I use the method isNotEligibleForDisability. Since my spell checker doesn't look at code it didn't tell me that the correct spelling is Eligable.

Page 301:
        There are problems with the example, see the discussion in RemoveSettingMethod.

Page 363:
        The references to the refactorings on this page are cross referenced with chapter references rather than the usual page references. Worse still, the chapter for Extract Class should be Chapter 7.


Errors in the fifth through eighth printing

Page 2:
        In the first paragraph "and identifies the type movie" should read "and identifies the type of movie".

Page 12:
        

I've been asked for more information about the double to int rounding. It happens when you have a compound assignment. In other words
        


        
        int foo=1;
        foo += 1.5;
        

        

compiles, as it is equivalent to


        
        int foo = 1;
        foo = (int) (foo + 1.5);
        

        

I haven't looked into the rationale behind this. (see Java Language Specification, section 15.26.2)
        


Page 25 :
        
        Caption on fig 1.7 "Sequence diagram before extraction..." should be "Sequence diagram after extraction..."
[Corrected in the 8th Printing]

Page 40:
In the code examples on pages 40 and 41 the references to the field _name should instead be _title

Page 76 :
        
        3rd para in "Duplicated Code". "in both classes then Pull Up Field (320)" should read "in both classes then Pull Up Method (322)"
[Corrected in the 8th Printing]

Page 98:
        The method testReadAtEnd is incorrect. I looked at my source files and found the method there to say


        public void testReadAtEnd() throws IOException {
                int ch = -1234;
                for        (int i = 0; i < 141; i++)
                        ch = _input.read();
                assertEquals("read at end", -1, _input.read());
        }
        

        Another reason to be glad that these days I'm auto-inserting source code!

Page 115:
In the third line, "rerun" should be "return"

Page 120:
        In the solution statement the phrase "Replace all references to the temp with the expression" should be replaced with "Replace all references to the temp with the new method"

Page 121 :
        
        In the last step of the mechanics, I say to use Replace Temp with Query (120), this should be replaced with a reference to Inline Temp (119). Otherwise I'd get a recursive refactoring. The problem continues in the example on page 122 where again the cross reference should be to Inline Temp (119). This was fixed incorrectly in the 8th printing (see below)
[Corrected in the 8th Printing]

Page 121:
        This was an incorrect fix to an earlier error. In the last line of the mechanics the refactoring 'Replace Temp with Inline Temp' should read 'Inline Temp'. The same problem occurs on page 122.

Page 153:
        In the second para, third line "As discussed in Lea by section..." should read "As discussed in Lea in section...."

Page 176:
        In the second para, (a step in the mechanics) "change the getting method" should read "change the setting method"

Page 176 :
        
        In the method numberOfOrdersFor the line that reads if (each.getCustomerName().equals(customer)) result++; should read if (each.getCustomer().equals(customer)) result++;
[Corrected in the 8th Printing]

Page 177 :
        
        In the first state of the method setCustomer the line that reads _customer = new Customer (customer); should read _customer = new Customer (arg);
[Corrected in the 8th Printing]

Page 185:
        In the second paragraph "biwise xor" shoudl read "bitwise xor"

Page 219 :
        
        "In a paragraph at around the middle of page, the sentence "...need a new method that returns the code" should read "...need a new method that returns an instance of the new class."
[Corrected in the 8th Printing]

Page 222 :
        
        "In the crossed out code, the method "public int getBloodGroup() {" should be "public int getBloodGroupCode() {" (I had just renamed it!)"
[Corrected in the 8th Printing]

Page 222:
        At the bottom of the page I make the method getCode private. I obviously can't do that while any clients of BloodGroup are using the method.

Page 225:
        The first mention of the create method is missing the static keyword.

Page 240:
        On this page and on later pages I use the method isNotEligibleForDisability. Since my spell checker doesn't look at code it didn't tell me that the correct spelling is Eligable.

Page 285 :
        
        The before code contains a rather more serious error than the refactoring is meant to help with as the assertion is always executed.
        The before code should read:
        


        void setValue (String name, int value) {
                if (name.equals("height")) {
                        _height = value;
                        return;
                }
                if (name.equals("width")) {
                        _width = value;
                        return;
                }
                Assert.shouldNeverReachHere();
        }
        

[Corrected in the 8th Printing]

Page 301:
        There are problems with the example, see the discussion in RemoveSettingMethod.

Page 313 :
        
        

The line of code that says

    
        
        Assert.isTrue("amount too large", amount > _balance);
        

        

is in error as the sense of the boolean is the wrong way round. A better line would be
        


        
        Assert.isTrue("sufficient funds", amount <= _balance);
        

[Corrected in the 8th Printing]

Page 324 :
        
        In the top code example the line double chargeAmount = charge (lastBillDate, date) should read double chargeAmount = chargeFor (lastBillDate, date). (I got the method name inconsistent with the diagrams.)
        
[Corrected in the 8th Printing]

Page 328 :
        
        In the motivation paragraph "Pull Down Method" should read "Push Down Method". (This is what happens when I don't use links for everything!)
        
[Corrected in the 8th Printing]

Page 363:
        The references to the refactorings on this page are cross referenced with chapter references rather than the usual page references. Worse still, the chapter for Extract Class should be Chapter 7.


Errors in the fourth printing

Page xx :
        
"Joshua suggested the idea of code sketches" should read "Joshua Kerievsky suggested the idea of code sketches"
[Corrected in the 5th Printing]

Page 2:
        In the first paragraph "and identifies the type movie" should read "and identifies the type of movie".

Page 12:
        

I've been asked for more information about the double to int rounding. It happens when you have a compound assignment. In other words
        


        
        int foo=1;
        foo += 1.5;
        

        

compiles, as it is equivalent to


        
        int foo = 1;
        foo = (int) (foo + 1.5);
        

        

I haven't looked into the rationale behind this. (see Java Language Specification, section 15.26.2)
        


Page 25 :
        
        Caption on fig 1.7 "Sequence diagram before extraction..." should be "Sequence diagram after extraction..."
[Corrected in the 8th Printing]

Page 40:
In the code examples on pages 40 and 41 the references to the field _name should instead be _title

Page 76 :
        
        3rd para in "Duplicated Code". "in both classes then Pull Up Field (320)" should read "in both classes then Pull Up Method (322)"
[Corrected in the 8th Printing]

Page 98:
        The method testReadAtEnd is incorrect. I looked at my source files and found the method there to say


        public void testReadAtEnd() throws IOException {
                int ch = -1234;
                for        (int i = 0; i < 141; i++)
                        ch = _input.read();
                assertEquals("read at end", -1, _input.read());
        }
        

        Another reason to be glad that these days I'm auto-inserting source code!

Page 115:
In the third line, "rerun" should be "return"

Page 120:
        In the solution statement the phrase "Replace all references to the temp with the expression" should be replaced with "Replace all references to the temp with the new method"

Page 121 :
        
        In the last step of the mechanics, I say to use Replace Temp with Query (120), this should be replaced with a reference to Inline Temp (119). Otherwise I'd get a recursive refactoring. The problem continues in the example on page 122 where again the cross reference should be to Inline Temp (119). This was fixed incorrectly in the 8th printing (see below)
[Corrected in the 8th Printing]

Page 121:
        This was an incorrect fix to an earlier error. In the last line of the mechanics the refactoring 'Replace Temp with Inline Temp' should read 'Inline Temp'. The same problem occurs on page 122.

Page 153:
        In the second para, third line "As discussed in Lea by section..." should read "As discussed in Lea in section...."

Page 176:
        In the second para, (a step in the mechanics) "change the getting method" should read "change the setting method"

Page 176 :
        
        In the method numberOfOrdersFor the line that reads if (each.getCustomerName().equals(customer)) result++; should read if (each.getCustomer().equals(customer)) result++;
[Corrected in the 8th Printing]

Page 177 :
        
        In the first state of the method setCustomer the line that reads _customer = new Customer (customer); should read _customer = new Customer (arg);
[Corrected in the 8th Printing]

Page 185:
        In the second paragraph "biwise xor" shoudl read "bitwise xor"

Page 193 :
        
"to declare that interval window implements Observable" should read  "to declare that interval window implements Observer" [Corrected in the 5th Printing]

Page 219 :
        
        "In a paragraph at around the middle of page, the sentence "...need a new method that returns the code" should read "...need a new method that returns an instance of the new class."
[Corrected in the 8th Printing]

Page 222 :
        
        "In the crossed out code, the method "public int getBloodGroup() {" should be "public int getBloodGroupCode() {" (I had just renamed it!)"
[Corrected in the 8th Printing]

Page 222:
        At the bottom of the page I make the method getCode private. I obviously can't do that while any clients of BloodGroup are using the method.

Page 225:
        The first mention of the create method is missing the static keyword.

Page 240:
        On this page and on later pages I use the method isNotEligibleForDisability. Since my spell checker doesn't look at code it didn't tell me that the correct spelling is Eligable.

Page 261 :
        
In Ron's story, 4th para, "Of course, as soon as you being inspecting..." but should be "Of course, as soon as you begin
inspecting..."
  [Corrected in the 5th Printing]

Page 285 :
        
        The before code contains a rather more serious error than the refactoring is meant to help with as the assertion is always executed.
        The before code should read:
        


        void setValue (String name, int value) {
                if (name.equals("height")) {
                        _height = value;
                        return;
                }
                if (name.equals("width")) {
                        _width = value;
                        return;
                }
                Assert.shouldNeverReachHere();
        }
        

[Corrected in the 8th Printing]

Page 300 :
        
        In the mechanics section the field should be made final at the end
        of process not at the begining.
[Corrected in the 5th Printing]

Page 301:
        There are problems with the example, see the discussion in RemoveSettingMethod.

Page 307 :
        
"Another reason to be wary of class.forName is that..."
should be:
"Another reason to be wary of Class.forName is that..." (Class should have a capital C)
[Corrected in the 5th Printing]

Page 307 :
        
"I can use a differenct approach...."
should be:
"I can use a different approach..." (spelling) [Corrected in the 5th Printing]

Page 311 :
        
"If the exception us checked, adjust the callers..."
should be:
"If the exception is checked, adjust the callers..."
[Corrected in the 5th Printing]

Page 313 :
        
        

The line of code that says

    
        
        Assert.isTrue("amount too large", amount > _balance);
        

        

is in error as the sense of the boolean is the wrong way round. A better line would be
        


        
        Assert.isTrue("sufficient funds", amount <= _balance);
        

[Corrected in the 8th Printing]

Page 324 :
        
        In the top code example the line double chargeAmount = charge (lastBillDate, date) should read double chargeAmount = chargeFor (lastBillDate, date). (I got the method name inconsistent with the diagrams.)
        
[Corrected in the 8th Printing]

Page 328 :
        
        In the motivation paragraph "Pull Down Method" should read "Push Down Method". (This is what happens when I don't use links for everything!)
        
[Corrected in the 8th Printing]

Page 333 :
        
"arguments are needed by the labor item, and some are not"
should be: "some arguments are needed..." (missing word) [Corrected in the 5th Printing]

Page 346 :
        
"Whenever we see two similar method" should be: "Whenever we
see two similar methods" (plural) [Corrected in the 5th Printing]

Page 346 :
        
"The statement method prints statements" should be: "The
statement method prints statements" (font) [Corrected in the 5th Printing]

Page 363:
        The references to the refactorings on this page are cross referenced with chapter references rather than the usual page references. Worse still, the chapter for Extract Class should be Chapter 7.


Errors in the third printing

Page xx :
        
"Joshua suggested the idea of code sketches" should read "Joshua Kerievsky suggested the idea of code sketches"
[Corrected in the 5th Printing]

Page 2:
        In the first paragraph "and identifies the type movie" should read "and identifies the type of movie".

Page 12:
        

I've been asked for more information about the double to int rounding. It happens when you have a compound assignment. In other words
        


        
        int foo=1;
        foo += 1.5;
        

        

compiles, as it is equivalent to


        
        int foo = 1;
        foo = (int) (foo + 1.5);
        

        

I haven't looked into the rationale behind this. (see Java Language Specification, section 15.26.2)
        


Page 25 :
        
        Caption on fig 1.7 "Sequence diagram before extraction..." should be "Sequence diagram after extraction..."
[Corrected in the 8th Printing]

Page 40:
In the code examples on pages 40 and 41 the references to the field _name should instead be _title

Page 76 :
        
        3rd para in "Duplicated Code". "in both classes then Pull Up Field (320)" should read "in both classes then Pull Up Method (322)"
[Corrected in the 8th Printing]

Page 98:
        The method testReadAtEnd is incorrect. I looked at my source files and found the method there to say


        public void testReadAtEnd() throws IOException {
                int ch = -1234;
                for        (int i = 0; i < 141; i++)
                        ch = _input.read();
                assertEquals("read at end", -1, _input.read());
        }
        

        Another reason to be glad that these days I'm auto-inserting source code!

Page 115:
In the third line, "rerun" should be "return"

Page 120:
        In the solution statement the phrase "Replace all references to the temp with the expression" should be replaced with "Replace all references to the temp with the new method"

Page 121 :
        
        In the last step of the mechanics, I say to use Replace Temp with Query (120), this should be replaced with a reference to Inline Temp (119). Otherwise I'd get a recursive refactoring. The problem continues in the example on page 122 where again the cross reference should be to Inline Temp (119). This was fixed incorrectly in the 8th printing (see below)
[Corrected in the 8th Printing]

Page 121:
        This was an incorrect fix to an earlier error. In the last line of the mechanics the refactoring 'Replace Temp with Inline Temp' should read 'Inline Temp'. The same problem occurs on page 122.

Page 153:
        In the second para, third line "As discussed in Lea by section..." should read "As discussed in Lea in section...."

Page 176:
        In the second para, (a step in the mechanics) "change the getting method" should read "change the setting method"

Page 176 :
        
        In the method numberOfOrdersFor the line that reads if (each.getCustomerName().equals(customer)) result++; should read if (each.getCustomer().equals(customer)) result++;
[Corrected in the 8th Printing]

Page 177 :
        
        In the first state of the method setCustomer the line that reads _customer = new Customer (customer); should read _customer = new Customer (arg);
[Corrected in the 8th Printing]

Page 185:
        In the second paragraph "biwise xor" shoudl read "bitwise xor"

Page 193 :
        
"to declare that interval window implements Observable" should read  "to declare that interval window implements Observer" [Corrected in the 5th Printing]

Page 219 :
        
        "In a paragraph at around the middle of page, the sentence "...need a new method that returns the code" should read "...need a new method that returns an instance of the new class."
[Corrected in the 8th Printing]

Page 222 :
        
        "In the crossed out code, the method "public int getBloodGroup() {" should be "public int getBloodGroupCode() {" (I had just renamed it!)"
[Corrected in the 8th Printing]

Page 222:
        At the bottom of the page I make the method getCode private. I obviously can't do that while any clients of BloodGroup are using the method.

Page 225:
        The first mention of the create method is missing the static keyword.

Page 240:
        On this page and on later pages I use the method isNotEligibleForDisability. Since my spell checker doesn't look at code it didn't tell me that the correct spelling is Eligable.

Page 241 :
        
In the code examples at the bottom of the page, the method isEligibleForDisability
should be isNotEligibleForDisability [Corrected in the 4th Printing]

Page 261 :
        
In Ron's story, 4th para, "Of course, as soon as you being inspecting..." but should be "Of course, as soon as you begin
inspecting..."
  [Corrected in the 5th Printing]

Page 285 :
        
        The before code contains a rather more serious error than the refactoring is meant to help with as the assertion is always executed.
        The before code should read:
        


        void setValue (String name, int value) {
                if (name.equals("height")) {
                        _height = value;
                        return;
                }
                if (name.equals("width")) {
                        _width = value;
                        return;
                }
                Assert.shouldNeverReachHere();
        }
        

[Corrected in the 8th Printing]

Page 300 :
        
        In the mechanics section the field should be made final at the end
        of process not at the begining.
[Corrected in the 5th Printing]

Page 301:
        There are problems with the example, see the discussion in RemoveSettingMethod.

Page 307 :
        
"Another reason to be wary of class.forName is that..."
should be:
"Another reason to be wary of Class.forName is that..." (Class should have a capital C)
[Corrected in the 5th Printing]

Page 307 :
        
"I can use a differenct approach...."
should be:
"I can use a different approach..." (spelling) [Corrected in the 5th Printing]

Page 311 :
        
"If the exception us checked, adjust the callers..."
should be:
"If the exception is checked, adjust the callers..."
[Corrected in the 5th Printing]

Page 313 :
        
        

The line of code that says

    
        
        Assert.isTrue("amount too large", amount > _balance);
        

        

is in error as the sense of the boolean is the wrong way round. A better line would be
        


        
        Assert.isTrue("sufficient funds", amount <= _balance);
        

[Corrected in the 8th Printing]

Page 315 :
        
        The problem statement should read "You are throwing an exception
        on a condition the caller could have checked first" (the refactoring applies to all exceptions, not just checked ones)
[Corrected in the 4th Printing]

Page 324 :
        
        In the top code example the line double chargeAmount = charge (lastBillDate, date) should read double chargeAmount = chargeFor (lastBillDate, date). (I got the method name inconsistent with the diagrams.)
        
[Corrected in the 8th Printing]

Page 328 :
        
        In the motivation paragraph "Pull Down Method" should read "Push Down Method". (This is what happens when I don't use links for everything!)
        
[Corrected in the 8th Printing]

Page 333 :
        
"arguments are needed by the labor item, and some are not"
should be: "some arguments are needed..." (missing word) [Corrected in the 5th Printing]

Page 346 :
        
"Whenever we see two similar method" should be: "Whenever we
see two similar methods" (plural) [Corrected in the 5th Printing]

Page 346 :
        
"The statement method prints statements" should be: "The
statement method prints statements" (font) [Corrected in the 5th Printing]

Page 363:
        The references to the refactorings on this page are cross referenced with chapter references rather than the usual page references. Worse still, the chapter for Extract Class should be Chapter 7.


Errors in the first and second printings

Page xx :
        
"Joshua suggested the idea of code sketches" should read "Joshua Kerievsky suggested the idea of code sketches"
[Corrected in the 5th Printing]

Page 2:
        In the first paragraph "and identifies the type movie" should read "and identifies the type of movie".

Page 12:
        

I've been asked for more information about the double to int rounding. It happens when you have a compound assignment. In other words
        


        
        int foo=1;
        foo += 1.5;
        

        

compiles, as it is equivalent to


        
        int foo = 1;
        foo = (int) (foo + 1.5);
        

        

I haven't looked into the rationale behind this. (see Java Language Specification, section 15.26.2)
        


Page 25 :
        
        Caption on fig 1.7 "Sequence diagram before extraction..." should be "Sequence diagram after extraction..."
[Corrected in the 8th Printing]

Page 37 :
        
"Class rental" should be "class Rental" (capitalization) and "class
movie" should be "class Movie" (capitalization)
[Corrected in the 3rd Printing]

Page 40:
In the code examples on pages 40 and 41 the references to the field _name should instead be _title

Page 48 :
        
The second line: "class Rental..." should be: "class Movie..." [Corrected in the 3rd Printing]

Page 70 :
        
Steve McConnell's last name is misspelled in two places. [Corrected in the 3rd Printing]

Page 76 :
        
        3rd para in "Duplicated Code". "in both classes then Pull Up Field (320)" should read "in both classes then Pull Up Method (322)"
[Corrected in the 8th Printing]

Page 82 :
        
        The sentence "If you add a new clause to the switch, you have to find all these switch, statements and change them." The second comma should be removed.
[Corrected in the 3rd Printing]

Page 85 :
        
"Replace Delegation with Inheritance (355)" in Inappropriate Intimacy should be "Replace Inheritance with Delegation (352)"  [Corrected in the 3rd Printing]

Page 92 :
        
        On Figure 4.1 the line from TestSuite to Test should be an association
        not a generalization (see diagram below). Also the
        package name should be junit.framework.
[Corrected in the 3rd Printing]

Page 92 :
        
        In the test file for the example, George Headley's career total was actually 2190 test riuns.
[Corrected in the 3rd Printing]

Page 98:
        The method testReadAtEnd is incorrect. I looked at my source files and found the method there to say


        public void testReadAtEnd() throws IOException {
                int ch = -1234;
                for        (int i = 0; i < 141; i++)
                        ch = _input.read();
                assertEquals("read at end", -1, _input.read());
        }
        

        Another reason to be glad that these days I'm auto-inserting source code!

Page 115 :
        
In the second sentence, "oustanding" should be "outstanding"
[Corrected in the 3rd Printing]

Page 115:
In the third line, "rerun" should be "return"

Page 120:
        In the solution statement the phrase "Replace all references to the temp with the expression" should be replaced with "Replace all references to the temp with the new method"

Page 121 :
        
        In the last step of the mechanics, I say to use Replace Temp with Query (120), this should be replaced with a reference to Inline Temp (119). Otherwise I'd get a recursive refactoring. The problem continues in the example on page 122 where again the cross reference should be to Inline Temp (119). This was fixed incorrectly in the 8th printing (see below)
[Corrected in the 8th Printing]

Page 121:
        This was an incorrect fix to an earlier error. In the last line of the mechanics the refactoring 'Replace Temp with Inline Temp' should read 'Inline Temp'. The same problem occurs on page 122.

Page 153:
        In the second para, third line "As discussed in Lea by section..." should read "As discussed in Lea in section...."

Page 176:
        In the second para, (a step in the mechanics) "change the getting method" should read "change the setting method"

Page 176 :
        
        In the method numberOfOrdersFor the line that reads if (each.getCustomerName().equals(customer)) result++; should read if (each.getCustomer().equals(customer)) result++;
[Corrected in the 8th Printing]

Page 177 :
        
        In the first state of the method setCustomer the line that reads _customer = new Customer (customer); should read _customer = new Customer (arg);
[Corrected in the 8th Printing]

Page 185:
        In the second paragraph "biwise xor" shoudl read "bitwise xor"

Page 193 :
        
"to declare that interval window implements Observable" should read  "to declare that interval window implements Observer" [Corrected in the 5th Printing]

Page 219 :
        
        "In a paragraph at around the middle of page, the sentence "...need a new method that returns the code" should read "...need a new method that returns an instance of the new class."
[Corrected in the 8th Printing]

Page 222 :
        
        "In the crossed out code, the method "public int getBloodGroup() {" should be "public int getBloodGroupCode() {" (I had just renamed it!)"
[Corrected in the 8th Printing]

Page 222:
        At the bottom of the page I make the method getCode private. I obviously can't do that while any clients of BloodGroup are using the method.

Page 225:
        The first mention of the create method is missing the static keyword.

Page 240:
        On this page and on later pages I use the method isNotEligibleForDisability. Since my spell checker doesn't look at code it didn't tell me that the correct spelling is Eligable.

Page 241 :
        
In the code examples at the bottom of the page, the method isEligibleForDisability
should be isNotEligibleForDisability [Corrected in the 4th Printing]

Page 261 :
        
In Ron's story, 4th para, "Of course, as soon as you being inspecting..." but should be "Of course, as soon as you begin
inspecting..."
  [Corrected in the 5th Printing]

Page 285 :
        
        The before code contains a rather more serious error than the refactoring is meant to help with as the assertion is always executed.
        The before code should read:
        


        void setValue (String name, int value) {
                if (name.equals("height")) {
                        _height = value;
                        return;
                }
                if (name.equals("width")) {
                        _width = value;
                        return;
                }
                Assert.shouldNeverReachHere();
        }
        

[Corrected in the 8th Printing]

Page 300 :
        
        In the mechanics section the field should be made final at the end
        of process not at the begining.
[Corrected in the 5th Printing]

Page 301:
        There are problems with the example, see the discussion in RemoveSettingMethod.

Page 307 :
        
"Another reason to be wary of class.forName is that..."
should be:
"Another reason to be wary of Class.forName is that..." (Class should have a capital C)
[Corrected in the 5th Printing]

Page 307 :
        
"I can use a differenct approach...."
should be:
"I can use a different approach..." (spelling) [Corrected in the 5th Printing]

Page 311 :
        
"If the exception us checked, adjust the callers..."
should be:
"If the exception is checked, adjust the callers..."
[Corrected in the 5th Printing]

Page 313 :
        
        

The line of code that says

    
        
        Assert.isTrue("amount too large", amount > _balance);
        

        

is in error as the sense of the boolean is the wrong way round. A better line would be
        


        
        Assert.isTrue("sufficient funds", amount <= _balance);
        

[Corrected in the 8th Printing]

Page 315 :
        
        The problem statement should read "You are throwing an exception
        on a condition the caller could have checked first" (the refactoring applies to all exceptions, not just checked ones)
[Corrected in the 4th Printing]

Page 324 :
        
        In the top code example the line double chargeAmount = charge (lastBillDate, date) should read double chargeAmount = chargeFor (lastBillDate, date). (I got the method name inconsistent with the diagrams.)
        
[Corrected in the 8th Printing]

Page 328 :
        
        In the motivation paragraph "Pull Down Method" should read "Push Down Method". (This is what happens when I don't use links for everything!)
        
[Corrected in the 8th Printing]

Page 333 :
        
"arguments are needed by the labor item, and some are not"
should be: "some arguments are needed..." (missing word) [Corrected in the 5th Printing]

Page 346 :
        
"Whenever we see two similar method" should be: "Whenever we
see two similar methods" (plural) [Corrected in the 5th Printing]

Page 346 :
        
"The statement method prints statements" should be: "The
statement method prints statements" (font) [Corrected in the 5th Printing]

Page 355 :
        
first line of section "Motivation", "...Replace Delegation with Inheritance (355)" should read "Replace Inheritance with Delegation (352)"  [Corrected in the 3rd Printing]

Page 363:
        The references to the refactorings on this page are cross referenced with chapter references rather than the usual page references. Worse still, the chapter for Extract Class should be Chapter 7.

Page 390 :
        
"...vivc.edu" should be "uiuc.edu"  [Corrected in the 3rd Printing]

Page 405 :
        
Parse tree for program should have "hello" (method name) in lower-case.
[Corrected in the 3rd Printing]

Page 405 :
        
Last box on bottom right should have "Hello World" (not "out")  [Corrected in the 3rd Printing]

Page 414 :
        
Reference to JUnit in the URL "compuserv" should be "compuserve"
[Corrected in the 3rd Printing]


Corrected version of fig 4.1 on page 92.



corrected figure 4.1





***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

BLOG main image

카테고리

분류 전체보기 (539)
이야기방 (19)
토론/정보/사설 (16)
IBM Rational (9)
U-IT (0)
SOA/WS/ebXML (110)
개발방법론/모델링 (122)
J2SE (34)
J2EE (60)
DataBase (39)
Open Projects (30)
BP/표준화 (50)
Apache Projects (15)
Web/보안/OS (22)
Tools (7)
AJAX/WEB2.0 (1)
Linux/Unix (1)
영어 (0)
비공개방 (0)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

달력

«   2025/06   »
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

글 보관함

Total :
Today : Yesterday :