Object-Oriented Analysis Design learning and exploration (6): good design = software flexibility (good design = flexible software)

Source: Internet
Author: User

Hope your software can be expanded more easily? When yourProgramWhen you encounter some problems that need to be modified, it may mean that your software needs to be extended more easily. To extend your software well, you need some analysis, overall design, and research on how object-oriented principles can decouple your software. Finally, you will find that high cohesion helps you solve coupling.

Back to the class diagram of the query tool, let's see what is unreasonable:

1. For the addinstrument method, you must add and modify each time you add a type of instrument.

2. For the search method, each time you add a musical instrument type, you must add a corresponding search method.

First, let's take a look at the modification of the search method:

To solve this problem, you must add an appropriate search method every time you add an instrument type. The key to this problem is that the instrumentspec type is an abstract type and cannot be instantiated. But can the problem be solved if it is changed to the actual type?

 

What does instruemntspec bring to us after it is changed to the actual type?

First, the search method changes:

Public list <instrument> Search (instrumentspec spec)

{

List <instrument> List = new list <instrument> ();

Foreach (Instrument instrument in inventory)

{

If (instrument. getspec (). Matches (SPEC ))

{

List. Add (instrument );

}

}

Return list;

}

Let's analyze:

Why is an instrument type required in this program?

Most instruments have at least a small public attribute, such as serial number and price. The Instrument Type stores these common attributes, and special instrument types can be extended from the instrument type.

What is the common part of all musical instruments?

Serial number, price, and some specifications, although the specifications may be different in different types of musical instruments

What is the difference between instruments?

Specifications: each instrument has different attributes and has different types and constructors.

Even though the search method looks better, the addment method in inventory still has some problems. The original program abstracted the instrument because each instrument type has a corresponding extension type.

Generally, an extension type is created because the extension type and super type behavior are different. But does guitar behave differently from other types of instruments in the query tool? They only have some different attributes but have no different behaviors. A problem arises: do we really need the extension types?

All the instruments in this query tool share the same behavior. Therefore, there are only two reasons for the extended type of instrument type:

1. Because instrument reflects a concept, it is not an actual object. We must create an extension type for each instrument type.

2. Each different instrument type has different attributes and uses different mentmentspec extension types. Therefore, we need to create a special constructor for each instrument.

It seems to be two good reasons, but the result is that the software is difficult to change. Do you still remember to write the second step of the software? Apply basic oo principles to add flexibility)

Inheritance, polymorphism, and abstraction are used in the original program. But now we should consider encapsulation changes. How to separate the changed part from the relatively stable part.

Now let's change the original design:

According to the above analysis, in fact, the extended type of instrument is only different in attributes, and the behavior of the type is not changed. Therefore, we can consider removing all extension types.

 

Now we need a new property named instrumenttype to indicate the type of the instrument. For different attributes of the instrument type, we can try to obtain them dynamically. The key to this problem is how we store these attributes. In fact, attributes are composed of only two parts: 1. attribute name 2. attribute value. You only need to map these two parts. Imagine using a hashtable object to store these attributes.

When your object has some changed attributes or uncertain attributes, you can use the set to dynamically store these attributes (when you have a set of properties that vary should ss you objects, use a collection, like a map, to store those properties dynamically .) the original book is written in Java, and the hashtable type can be used in DOTNET.

In this way, you can remove many methods from the original type and avoid modifying the attributes when adding them.CodeIn your program (you'll remove lots of methods from your classes, and avoid having to change your code when new properties are added to your app .)

Now let's look at how to design the instrument and instrumentspec types in the program.

Next, go to the Code to see how the program is written:

Public class instrumentspec

{

Private hashtable _ properties;

Public instrumentspec (hashtable properties)

{

If (properties! = NULL)

{

_ Properties = properties;

}

Else

{

_ Properties = new hashtable ();

}

}

Public object getproperty (string propertyname)

{

Return _ properties [propertyname];

}

Public hashtable getproperties ()

{

Return _ properties;

}

Public Boolean matches (instrumentspec otherspec)

{

Boolean flag = true;

Hashtable otherproperties = otherspec. getproperties ();

Foreach (dictionaryentry de in otherproperties)

{

String propertyname = de. Key. tostring ();

If (_ properties [propertyname]! = De. value)

{

Flag = false;

Break;

}

}

Return flag;

}

}

Public class inventory

{

Public Inventory ()

{

_ Instruments = new list <instrument> ();

}

Private list <instrument> _ instruments;

Public list <instrument> Instruments

{

Get {return _ instruments ;}

Set {_ instruments = value ;}

}

Public void addinstrument (string serialnumber, double price, instrumentspec spec)

{

Instruments. Add (New Instrument (serialnumber, price, spec ));

}

Public list <instrument> Search (instrumentspec spec)

{

List <instrument> List = new list <instrument> ();

Foreach (Instrument instrument in _ instruments)

{

If (instrument. spec. Matches (SPEC ))

{

List. Add (instrument );

}

}

Return list;

}

}

Public Enum instrumenttype

{

Guitar, Banjo, Dobro, fiddle, bass, mandolin

}

The instrument type is similar to the previous one:

Public class Instrument

{

Public instrument (string serialnumber, double price, instrumentspec spec)

{

_ Serialnumber = serialnumber;

_ Price = price;

_ Spec = spec;

}

Private string _ serialnumber;

Private double _ price;

Private instrumentspec _ spec;

Public String serialnumber

{

Get {return _ serialnumber ;}

Set {_ serialnumber = value ;}

}

Public double price

{

Get {return _ price ;}

Set {_ price = value ;}

}

Public instrumentspec spec

{

Get {return _ spec ;}

Set {_ spec = value ;}

}

}

Test it with a client program:

Class Program

{

Private Static inventory;

Static void main (string [] ARGs)

{

Inventory = new inventory ();

Inventoryinit ();

Findinstrument ();

Console. Read ();

}

Static void findinstrument ()

{

Hashtable findprops = new hashtable ();

Findprops. Add ("Builder", "Collings ");

Findprops. Add ("model", "cj1 ");

Instrumentspec findspec = new instrumentspec (findprops );

List <instrument> List = inventory. Search (findspec );

If (list. Count> 0)

{

Foreach (Instrument instrument in List)

{

Console. writeline ("find the serialnumber is" + instrument. serialnumber. tostring ());

}

}

Else

{

Console. writeline ("can not find ");

}

}

Static void inventoryinit ()

{

Hashtable properties = new hashtable ();

Properties. Add ("instrumenttype", instrumenttype. Guitar );

Properties. Add ("Builder", "Collings ");

Properties. Add ("model", "CJ ");

Properties. Add ("type", "acoustic ");

Properties. Add ("numstrings", 6 );

Properties. Add ("topwood", "Indian ");

Properties. Add ("backwood", "Sitka ");

Inventory. addinstrument ("11277", 4000, new instrumentspec (properties ));

Hashtable properties2 = new hashtable ();

Properties2.add ("instrumenttype", instrumenttype. mandolin );

Properties2.add ("Builder", "Collings ");

Properties2.add ("model", "cj1 ");

Properties2.add ("type", "acoustic ");

Properties2.add ("numstrings", 6 );

Properties2.add ("topwood", "Indian ");

Properties2.add ("backwood", "Sitka ");

Inventory. addinstrument ("11278", 4000, new instrumentspec (properties2 ));

}

}

Output result:

 

I have done a lot of work on this query tool, but don't forget what we want to do! Now let's take a look at the class diagram of this program:

Let's take a look at the several questions:

1. If you want to add a new instrument type, how many existing types need to be added?

Existing programs do not need to add new types. Now we have removed all instrument types from the instruments and instrumentspec types.

2. How many existing types do I need to change if I change the type of an instrument?

One. Modify the instrumenttype and add a new instrument type.

3. If the customer asks to record the production time of each instrument, how many types of changes need to be made?

No. You can add it to the properties of instrumentspec.

4. If the customer modifies the attributes of a certain instrument, how many types need to be changed?

If the attribute value has nothing to do with other types, it does not need to be changed. However, if the attribute value is of an enumeration type, there is a type that needs to be changed.

Now it seems that the program is easier to expand than before, but what is cohesive )? The cohesion type only does one thing and does nothing else (a cohesive class does really well and does not try to do or be something else)

Cohesion represents the degree of connection between elements. Including the module, type, or object. Software High Cohesion describes the responsibilities of a single type of application. Remember in the previous articleArticle(Oo catastrophe) has the following sentence: "Every class shocould attempt to make sure that it has only one reason to this, the death of your a badly designed piece of software ".

Now let's talk about cohesion. Do you still remember the "changes" mentioned in the previous chapter? Every class shocould attempt to make sure that it has only one reason to this, the death of every a badly designed piece of software. in fact, it means that each type has only one change point or only one reason. Cohesion is manifested in the degree of closeness between types in the program. Remember the example of the car?

Each type method is relatively well defined. Each type is a high cohesion type and is easy to change, but does not affect other types. Come back and see if our changes have made the instrument's query tool highly cohesive? Is the objects in the program decoupled? Is it easy to cope with changes?

From this lesson, we can sum up some things about object-oriented analysis design. Let's see how much we know.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.