1. Trang chủ
  2. » Công Nghệ Thông Tin

C# 3.0 Design Patterns PHẦN 3 pps

32 430 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 32
Dung lượng 224,71 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Here isOpenBook in its most rudimentary form: public class MyOpenBook : Bridge { // Combination of a virtual and authentication proxy SpaceBook mySpaceBook; string name; static int u

Trang 1

The second implementation of theBridge interface in this example also happens to

be aProxyto SpaceBook Most of theProxymechanisms have been stripped out, andall that remains is the smart proxy operation of keeping a serial count of users Here

isOpenBook in its most rudimentary form:

public class MyOpenBook : Bridge {

// Combination of a virtual and authentication proxy

SpaceBook mySpaceBook;

string name;

static int users;

public MyOpenBook (string n) {

public void Add(string friend, string message) {

mySpaceBook.Add(friend, name + " said: "+message);

myOpenBook.Add(who, what+" you");

static class OpenBookExtensions {

public static void SuperPoke (this Portal me, string who, string what) { me.Add(who, what+" you");

}

}

Trang 2

Example: OpenBook | 43

and call it the same way we call the other methods:

tom.SuperPoke("Judith-1","hugged");

Extension methods are one of the new features in C# 3.0

The full program for the OpenBook extension is given in Example 2-6 TheSpaceBookandMySpaceBookclasses from Example 2-4 were not altered in any way andare given as headers only to save space In this output, Judith has switched to Open-Book and therefore has the name Judith-1 Tom, as the second OpenBook user, isgiven the name Tom-2

C# 3.0 Feature—Extension Methods

Extension methods allow developers to add new methods to an existing type withouthaving to create an inherited class or to recompile the original Thus, you can addmethods to classes for which you might not even have the sources (e.g., System String) An extension method is defined the same way as any other, with twostipulations:

• It is declared asstatic in an outer-level static, nongeneric class.

• The type it is extending is declared as the first parameter, preceded bythis.The method can then be called as an instance method on an object of the type that hasbeen extended

cf C# Language Specification Version 3.0, September 2007, Section 10.6.9

Example 2-6 Bridge pattern example code—OpenBook

using System;

using System.Collections.Generic;

// Bridge Pattern Example Judith Bishop Dec 2006, Aug 2007

// Extending SpaceBook with a second implementation via a Portal

Trang 3

// Bridge

interface Bridge {

void Add(string message);

void Add(string friend, string message);

void Poke(string who);

public class MySpaceBook { }

// A Proxy with little to do

// Illustrates an alternative implementation of the Bridge pattern public class MyOpenBook : Bridge {

// Combination of a virtual and authentication proxy

SpaceBook myOpenBook;

string name;

static int users;

public MyOpenBook (string n) {

public void Add(string friend, string message) {

myOpenBook.Add(friend, name + " : "+message);

static class OpenBookExtensions {

public static void SuperPoke (this Portal me, string who, string what) { me.Add(who, what+" you");

}

}

// The Client

class BridgePattern : SpaceBookSystem {

static void Main ( ) {

Example 2-6 Bridge pattern example code—OpenBook (continued)

Trang 4

Example: OpenBook | 45

Portal me = new Portal(new MyOpenBook("Judith"));

me.Add("Hello world");

me.Add("Today I worked 18 hours");

Portal tom = new Portal(new MyOpenBook("Tom"));

Today I worked 18 hours

Tom poked you

Tom : hugged you

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

======== Judith-1's SpaceBook =========

Hello world

Today I worked 18 hours

Tom poked you

Tom : hugged you

Tom : Poor you

Trang 5

Bridge is a very simple, but very powerful pattern Given a single implementation, wecan add a second one together with a Bridge and an Abstraction and achieveconsiderable generality over the original design

A well-quoted use of the Bridge pattern is in graphics, where different displays havedifferent capabilities and drivers These would be the implementations of the Bridgepattern, and the Bridge would be an interface of their essential capabilities TheClientcalls theAbstractionto display something, and theAbstractioncan examinethe properties of the one or more Bridgeinstances (drivers) it is holding and selectthe most appropriate one for the task

Exercise

1 Although some limited operations can be added to OpenBook, the fact thatsome fundamental ones, such as the page header, are embedded in the privateSpaceBookclass makes real change difficult Assuming that you can negotiate anupgrade with the developers of SpaceBook, make a proposal, including a UMLdiagram, for the long-term design of an extensible system Implement it

Pattern Comparison

The careful reader might have noticed that the three patterns described in this ter seem to offer much the same service At a high level, they are all helping to extendclasses in novel ways, and they all provide alternatives to inheritance A summary ofwhen each pattern might be used was provided at the end of each section Becausethis is also a programming book, we’ll now summarize the object mechanisms thepatterns use (see Table 2-2) and draw conclusions about their comparative opera-tion This summary is based on the UML diagrams and theory code for each of thepatterns

chap-In each pattern, we can identify four roles, which can fall under the headings

origi-nal, new, interface, and client The actual names given to these meta-roles are shown

in the first three rows of the table Note that the Bridge pattern can work in twoways In our examples, we used the “Bridge-up” option We assumed that we had

Use the Bridge pattern when…

You can:

• Identify that there are operations that do not always need to be implemented in the same way

You want to:

• Completely hide implementations from clients

• Avoid binding an implementation to an abstraction directly

• Change an implementation without even recompiling an abstraction

• Combine different parts of a system at runtime

Trang 6

Pattern Comparison | 47

one implementation already and wanted to share its interface with other tations yet to be built To do so, we needed to create anAbstractionthat was closelyconnected to theBridgeinterface An equally valid application for the Bridge patternwould be to have an original abstraction in mind and to build it hand-in-hand withthe implementations (the “Bridge-down” approach)

implemen-As you can see in the fourth row of the table, variations are found in the clients Forexample, the Decorator pattern aggregates the interface so that it can share decora-tions; it provides the original as a construction parameter The Bridge-up patterndoes the same To make this more concrete, here are the two statements from theclients:

// Decorator

Display(new DecoratorA(new IComponent( ));

// Bridge-up

Console.WriteLine(new Abstraction(new ImplementationA( )).Operation( ));

The fifth row shows what objects are invoked in the pattern The Decorator patterncan call the original components or the decorators, but the Bridge pattern variationsonly call one or the other The Proxy pattern both aggregates and invokes only thenew classes

Table 2-2 Comparison of Decorator, Proxy, and Bridge patterns

Original Component Subject Abstraction Implementation

Client aggregates New with interface New Original with new New with original

Client activates Original and new New Original New

Original changed by Implementing the

interface

No change Aggregating the

interface

Implementing the interface

New classes Aggregate the

interface Implement the interface

Aggregate the original Implement the interface

Implement the interface

Aggregate the interface

Operation routed From new to original From new to original From original to new From new to original

Trang 7

The next row itemizes how the original changes as a result of the pattern Only theProxy pattern enables the original to remain completely unchanged The Decoratorpattern relies on there being an interface that everyone implements, which mighthave to be added after the original classes are developed The Bridge pattern is moreclosely coupled, and there is an understanding that the original must incorporateconsiderable references to the rest of the system.

All the patterns rely on rerouting operations The last row in the table shows that thererouting is always done from the new code back to the original; in the case of theBridge pattern, it just depends on which class is called new and which class is calledthe original It is worth noting that in real-time applications, where reaction time isimportant, the overhead of the time for rerouting the operations might not beacceptable

Trang 8

Computer applications that specialize in grouping data abound these days Consider

a music playlist in iTunes or a digital photo album in Flickr or iPhoto (Figure 3-1).Items are put in a large list, which is then given structure separately

Trang 9

Looking at the screenshot from iPhoto, we can see that there are different ways ofviewing the photos that have been imported: chronologically or by named event A sin-gle photo can appear in many albums (“Last Roll,” “2007,” and “Switzerland,” forexample) Creating an album forms a composite object but does not entail actuallycopying the photos In this context, the important point about the Composite pattern

is that the operations carried out on photos and albums of photos should have thesame names and effects, even though the implementations are different For example,the user should be able to display a photo or an album (that contains photos) Simi-larly, deletions of a single photo or an album should behave in the same way

Design

The Composite pattern is one of the simplest there is, on the face of it It has to dealwith two types:Components and Composites of those components Both types agree toconform to an interface of common operations Composite objects consist ofComponents, and in most cases, operations on aCompositeare implemented by callingthe equivalent operations for its Componentobjects See Figure 3-2 for the UML dia-gram for this pattern

The essential players in the Composite pattern UML diagram are:

Trang 10

Implements the operations as applicable to composite objects, using (or accessing)

a list of components kept locally and probably using the equivalent Componentoperations

The client deals only with theIComponent interface, which simplifies its task

Figure 3-2 Composite pattern UML diagram

Q U I Z

Match the Composite Pattern Players with the iPhoto Illustration

To test whether you understand the Composite pattern, cover the lefthand column ofthe table below and see if you can identify the players among the items from the illus-trative example (Figure 3-1), as shown in the righthand column Then check youranswers against the lefthand column

IComponent Component Composite Operation

A visible entity in iPhoto

A single photo

An album of photos Open and view

Trang 11

Although our illustration referred to photos and albums, the design and tion of the Composite pattern is completely independent from the kind of basic com-ponent being handled We could equally well be dealing with groups of people or bankaccount portfolios The composite operations, however, have to iterate through astructure of these components To realize both the flexibility of components of any

implementa-type and a connection between leaf and composite, we can use the C# generics feature.

By declaringIComponent,Component, andCompositeas generic types, we create an mentation of the Composite pattern that can be instantiated in a practical example

imple-For the Composite pattern, we will not create a program, but a

namespace containing two classes,Composite and Component , and an

interface, IComponent

Starting with theIComponentinterface, we declare it as a generic of typeT Then each

of the anticipated operations follows:

public interface IComponent <T> {

void Add(IComponent <T> c);

IComponent <T> Remove(T s);

IComponent <T> Find(T s);

string Display(int depth);

T Item {get; set;}

}

C# Feature—Generics

Generics are an extension to the type system whereby structs, classes, interfaces, gates, and methods can be parameterized with types For example, a generic type likeList<T>is a generator for constructed types likeList<string>andList<Person> All thecollections in the NET Framework library used by C# are available in generic form.They includeDictionary, Stack, Queue, and List, plus variations on them There arealso generic methods such asSortandBinarySearch These require the types they areworking on to implement theIComparerinterface so that comparisons between ele-ments can be done correctly

dele-To specify a generic type or method, use the generic parameters in angle brackets, as

in<T>or<T, P> The generic type can be used to specify further generic elements, againusing the<T> format, or it can be used normally as a type, as in T.

To construct an actual type or method from a generic one, supply actual types for each

of the generic parameters, as in<string>.

cf C# Language Specification Version 3.0, September 2007, Section 10.1.3

Trang 12

Composite Pattern | 53

Because the types will be in a separate namespace, they must all be

declared as public

Why doAdd,Remove, andFindrefer toIComponent <T>andRemoveandFindrefer toT

as well? What is the difference between <T> and T? Recall that an object of typeIComponentis either aComponentor aCompositeand will have state associated withbeing anIComponent, in addition to the actual value of the element it is storing Theelement is of the type T, so in the case ofFindandRemove, we pass as parametersthe actual element values of typeT For example, if the interface were instantiatedwithTas anImage, we would pass anImageobject toFindand in return get a refer-ence to anIComponentobject The returned object would contain theImageobject ifthe search were successful

The last line of the interface is interesting because it introduces a new syntax for erties in classes Before C# 3.0, this new syntax was only present in interfaces It hasnow been extended to classes as well and makes programs shorter and easily readable

prop-Now, let’s consider how the Componentclass would be implemented in accordancewith theIComponent interface, as in the namespace shown in Example 3-1

C# 3.0 Feature—Properties and Accessors

A property gives controlled access to the private local state of an object, either directly

to its fields or via some computation Properties define one or two accessors:getand/

orset The most common form of a property is:

public type Field {get; set;}

whereFieldis an identifier This declaration creates a private field and makes it sible for public reading and writing via the nameField

acces-By placing such properties in an interface, we are effectively requiring classes to supplyproperty accessors as well as the usual methods when implementing the interface.Properties can omit either thegetor thesetaccessor; it is more typical to omit theset,which makes the property read-only

Properties can also compute the result of agetorset, in which case, the expanded tax is:

syn-public type Field {

get { statements; return expression; }

set { statements including reference to value; }

Trang 13

Example 3-1 Composite pattern—namespace code

17 public class Component <T> : IComponent <T> {

18 public T Name {get; set;}

24 public void Add(IComponent <T> c) {

25 Console.WriteLine("Cannot add to an item");

26 }

27

28 public IComponent <T> Remove(T s) {

29 Console.WriteLine("Cannot remove directly");

30 return this;

31 }

32

33 public string Display(int depth) {

34 return new String('-', depth) + Name+"\n";

46 public class Composite <T> : IComponent <T> {

47 List <IComponent <T>> list;

Trang 14

Composite Pattern | 55

The namespace starts off with the definition of the interface with its four methodsand one property Then follows theComponentclass Not all ofIComponent’s methodsare meaningful forComponents Adding and removing are done only inComposites, so

53 list = new List <IComponent <T>> ( );

62 // Finds the item from a particular point in the structure

63 // and returns the composite from which it was removed

64 // If not found, return the point as given

65 public IComponent <T> Remove(T s) {

76 // Recursively looks for an item

77 // Returns its reference or else null

78 public IComponent <T> Find (T s) {

90 // Displays items in a format indicating their level in the composite structure

91 public string Display(int depth) {

92 StringBuilder s = new StringBuilder(new String('-', depth));

93 s.Append("Set "+ Name + " length :" + list.Count + "\n");

94 foreach (IComponent <T> component in list) {

Trang 15

a simple error message is written out (see the upcoming “Exercises” section for anextension on this point) In the Component’s Find method (lines 37–42), the classrelies on the actual type parameter forThaving anEqualsmethod If it does not, thegeneric instantiation will fail at compile time.

TheDisplay method (lines 33–35) also assumes that the field accessed by theNameproperty has a ToString method defined In fact, only string-like types will workproperly here, so it is likely that theDisplaymethod should be defined later (see theupcoming “Exercises” section.)

TheCompositeclass also implements theIComponentinterface (line 46) TheFindandRemovemethods of the Compositeare more elaborate than those in theComponentsothat they can handle arbitrary structures of composites and components Let’s look

at some of the more interesting statements:

• The Composite keeps as a list a local structure that consists ofComponents andComposites (line 47) When the contents areComposites, a new object is created,

as well as a new list The list is declared as:

List <IComponent <T>> list;

This shows that an open generic type can be used as a parameter to anothergeneric type

• The logic ofRemove(lines 65–74) is that we first find the item in the structureand then, if it is there, we remove it from the list structure held locally in theComposite (line 69):

• The call toFindwill go to the appropriate method, depending on the actual type of

cat runtime This supports the Composite pattern’s ideal of havingComponents andComposites be treated the same

That completes the theoretical Composite pattern implementation Apart from theconcern with theDisplaymethod, the three preceding types can be used together forany elements Thus, we can put them in a namespace calledCompositePatternfor use

in the next example.Example: Photo Library

In this example, we are concerned with collecting the filenames of digital photos intonamed sets We will not use actual images in this example, just filenames as strings.The client is given a domain-specific set of commands with which to create andmanipulate the library Central to the manipulation of the library, from the user’spoint of view, is “where we are.” We start out at an empty set called “Album.” Some

Trang 16

Composite Pattern | 57

of the commands leave the system at the component that has just been adjusted,whereas others move it back to the first component in the set The commands are:AddSet

Add a new empty set with a name and stay there

Exit the program

Thus, the two operations that work on eitherComponents orComposites areFindandRemove Consider some examples of the workings of this system, illustrated inExample 3-2 The input commands are shown in the middle, the result ofDisplayisshown on the left, and some commentary appears on the right

The input file contains all the commands in the middle The program

will expect this file to be called Composite.dat.

Example 3-2 Composite pattern—Photo Library sample run

Display Returns to start of Album

Set Album length :2

Set Home length :2

Ngày đăng: 12/08/2014, 09:22

TỪ KHÓA LIÊN QUAN