C # design mode

xiaoxiao2021-03-06  56

Textbook: "C # Design Mode", Electronic Industry Press, ISBN 7-5053-8979-3.33 yuan contains CD. Course content: Design mode Source: Alexander's architectural mode, Gamma et al. (1995) created "Design Patterns: Elements of Reusable Software". This book is often referred to as "Gang of Four" or "GOF", which created "design mode". Some people say "36" is "mode".

First, C # object-oriented programming review

Click http://www.cnblogs.com/files/zhenyulu/csharp.rar download, including: fields and properties .cs attribute, method scope. CS plus one hundred .CS Using interface sort (2) .cs Use the interface sort (1). CS sequencing. C 泡 法. CS nine nine table. CS static and non-static .CS constructor.cs method overload. CS polymorphism. CS recursive sections. CS print triangle .CS pass value call and reference call. CS

Second, the design pattern example

There is a model called Builder mode in the design mode, the principle is as follows:

We can understand the Builder into a rice cooker, put the Builder in the rice and water. After the Builder's Build, we can take out the fragrant rice. There is a class called StringBuilder in C #, and after entering the necessary information, the corresponding String can be taken out. The method of use is as follows:

Using

System;

Using

System.Text;

Class

Exam

{Public static void main () {StringBuilder SB = new stringbuilder (); sb.append ('a', 2); sb.append ('b', 3); sb.append ('c', 4); console .Writeline (sb.tostring ()); // Print Aabbbcccc Sb.Remove (0, Sb.Length); // Clear all information in SB}}

The program execution result is: AABBBCCCC Please use StringBuilder to rewrite the following printed triangle procedures, write a new program.

Using

System;

public

Class

Exam

{Public static void main () {console.write ("Please enter the number of rows:"); console.writeline (""); for (int i = 0; I <= line; i ) {for (int K = 1; k <= lines-i; k ) console.write (""); for (int J = 1; j <= i * 2 1; j ) Console.write ("*"); console.writeline ("");}}}

answer:

Using

System;

Using

System.Text;

Class

Exam

{Public static void main () {console.write ("Please enter the number of lines:"); console.veline ()); console.writeline (""); stringbuilder sb = new stringbuilder () ; For (int i = 0; i <= lines; i ) {sb.append ('', line-i); sb.append ('*', i * 2 1); console.writeLine (sb.toString ()); Sb.remove (0, sb.Length);}}} III, first with chicken or eggs first?

Do you have a chicken or an egg before? Look at the following code:

Using

System;

Class

Client

{Public static void main () {base b = new base (); derived d = new derived (); b.d = D; console.writeline (b.d.m);}}

Class

Base

{Public int n = 9; public derived d;}

Class

Derived: Base

{Public int m = 10;}

Derived Inherited from Base, it can be said that there is no Base, there is no derived, and there is a member in Base to be the derived type. Do you have a chicken or an egg before? This program can perform and print results normally and print results 10.

Fourth, big bottle set small bottle or small bottle set big bottle?

Another example:

Using

System;

Class

Client

{Public static void main () {a a = new a (); b = new b (); A.B = B; B.A = a;}}

Class

A

{Public B b;}

Class

B

{Public a a;

The above code seems to describe the relationship between "A contains B, B contains a". Is it a large bottle of a small bottle or a small bottle?

Five, .NET nature

With regard to the procedural procedures for "first with chicken or first eggs", the system is running, the memory structure is as follows:

As can be seen from the figure, there is no problem with the problem of chickens and eggs, but the problem with the value and the problem reference.

With regard to "big bottle set small bottle or small bottle set big bottle", after the system is running, the memory structure is as follows: Since it is a pointer reference, it doesn't matter that a big bottle is still a small bottle.

About more items can be referred to ". NET INTORE Volume 1: Public Language Operations".

"Moon Moon Myth" tar, no silver bomb * software corruption:

Design Goal in the problem -------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------- Will not affect other) Reuse rate low viscosity excessive insertability (new features easy to join the system (airbags join steering wheel))

* Several principles to improve system-reuse: Traditional multiplexing: 1. Code's splitter multiplexing 2. Algorithm multiplexing 3. Data structure multiplexing * Upper maintenance and reusability is not complete

* Support for maintainability:

First, "Open-Closed" principle (OCP)

The Open-Closed PrinciPle principle is: A software entity should be open to the extension and turn it off for modification.

Advantages: By expanding existing software systems, new behaviors can be provided to meet new demands for software, so that the software in the change has certain adaptability and flexibility. Software modules, especially the most important abstract layer modules, can no longer be modified, which makes changes in the software system in the change and continuity.

Example: Yu Emperor Zhao An Monkey King is the new challenge of Monkey King to Yu Emperor. The Monkey King said: "The emperor turns, next year to my house." Just teach him to move out, let the Tiangong for me! "For this challenge, Taibai Jinxing gives the Emperor's Emperor's Suggestion is:" Down to enrich the sacred sacred sacred The upper industry came ..., a non-labor division, the second fairy has a road. "

In other words, regardless of the people, do not destroy the sky, it is "closed", and there is a "open". The Tao of Zhao'an is the "open-closed" principle of Yu Emperor.

The key to the law of Anto is not allowing to change the existing heaven or order, but allowing the demon monkey to be included in the existing order, thereby expanding this order. In terms of object-oriented languages, it is not allowed to change the abstraction layer of the system, while allowing changes to the system's implementation layer.

Second, the principle of replacement of the Rich (LSP)

Liskov Substitution PrinciPle: Subtype must be able to replace their base type.

White horse, black horse

In the case of the replacement of the "Mozi · Xiao Take" said: "娣, beauty, love, non-love beauty ..." 便 是, brother loves the sister, because the two are brothers and sister relations, not Because my sister is a beautiful person. Therefore, love your sister is not equivalent to love the beauty. Describe the object-oriented language, the beauty is a base class, and the sister is a child of beauty. Good brother as a "love ()" method, accepting his sister as a parameter. So, this "love ()" method generally does not accept instances of the beauty.

A simple example of violating LSP (rectangular and square)

public

Class

Rectangle

{Private long width; private long height; public void setWidth (long width) {this.width = width;} public long getWidth () {return this.width;} public void setHeight (long height) {this.height = height; } Public long getheight () {return this.Height;}}

public

Class

Square

{Private long side; public void setside (long side) {this.SIDE = Side;} public long getside () {returnire;}}

Squares can not be a roofer

Using

System;

public

Class

Rectangle

{Private long width; private long height; public void setWidth (long width) {this.width = width;} public long getWidth () {return this.width;} public void setHeight (long height) {this.height = height; } Public long getheight () {return this.Height;}}

public

Class

Square: Rectangle

{Private long side; public void setWidth (long width) {setSide (width);} public long getWidth () {return getSide ();} public void setHeight (long height) {setSide (height);} public long getHeight () {Return getside ();} public long getside () {returnide;} public void setside (long side) {this.side = side;}}

public

Class

Smarttest

{Public void resize {while (r.getHeight ()> = r.GetWidth ()) {r.SetWidth (r.GetWidth () 1);}}}

When executing the resize method of the SmartTest, if the incoming rectangular object, when the height is greater than the width, the width is automatically increased until the height is exceeded. However, if the square object is incorporated, it will fall into the dead cycle.

Refactoring

public

Interface

Quadrangle

{Public long getWidth (); public long getHeight ();

public

Class

Rectangle: Quadrangle

{Private long width; private long height; public void setWidth (long width) {this.width = width;} public long getWidth () {return this.width;} public void setHeight (long height) {this.height = height; } Public long getheight () {return this.Height;}}

public

Class

Square: quadrangle

{Private long side; public void setSide (long side) {this.side = side;} public long getSide () {return side;} public long getWidth () {return getSide ();} public long getHeight () {return getSide ();}} III, Dependency Inversion Principle (DIP)

Dependency Inversion PrinciPle is: To rely on abstraction, don't depend on specific.

Simply put, relying on the inverting principle requires the client depending on abstract coupling. Principle expressed:

Abstractions should not depend on the details; details should depend on abstraction; to program the interface for interfaces, not for programming.

Brief example: Disadvantages: Coupling is too tight, Light changes will affect Toggleswitch.

Solution 1: Make the light into Abstract, then inherit the specific class from Light.

Advantages: Toggleswitch depends on abstract class Light, with higher stability, and Bulblight and Tubelight are inherited from Light, which can be expanded according to the "open-closed" principle. As long as Light does not change, the changes in Bulblight and Tubelight will not affect Toggleswitch.

Disadvantages: If you control a TV with Toggleswitch is very difficult. You can't keep TV inheritance from Light.

Solution 2:

Advantages: More common, more stable.

Conclusion: Use the dependencies created by traditional processes to design, strategies dependent, which is bad because the strategy is affected by details. Relying on the inverting principle The details and strategies depend on abstraction, and abstract stability determine the stability of the system.

Fourth, the interface isolation principle (ISP)

Interface SEGREGATION Princi PRINCIPLE: Using multiple dedicated interfaces is better than using a single total interface. In other words, from a customer class: a class of dependencies on another class should be based on the minimum interface.

Too bloated interface is contamination of the interface. It should not force customers to rely on how they don't need.

My Object-Oriented Umbrella (Excerpted from Design Patterns Explained)

Let me Tell You About My Great Umbrella. It is large enough to get ket in! In Fact, Three Or Four Other People Can get in it with me. While we are in it, staying out of the rain, i can move it from one Place to another. it has a stereo system to keep me entertained while i stay dry. Amazingly Enough, IT can Also Condition The Air To make it it warmer or folder. It is one cool umbrella.

My Umbrella Is Convenient. IT HAS WHEELE WAITING IT I do Not Have To Carry It Around. I don't evening to push it because it can propel itself. Sometimes, I will open the top of my umbrella to let in the sun. (Why I am using my umbrella when it is sunny outside is beyond me!) in Seattle, there are hundreds of thousands of these umbrellas in all kinds of colors. Most people call them cars.

Implementation: 1. Use the delegate separation interface 2, use multiple inheritance separation interfaces

V. Synthesis / Polymerization Multiplexed Principles (Carp)

Composite / AGGREGATE Reuse Principle or CARP is often called the synthetic reuse principle (Composite Reuse Principle or CRP), which is used in a new object to use some existing objects to make it a new object. Some; new objects reached the purpose of multiplexing the delegation to these objects.

In short, try to use synthetic / polymerization as much as possible, try not to use inheritance.

o Design to interfaces.o favor composition over inheritance.o find what varies and encapsulate it. (Excerpted from: Design Patterns Explained)

Distinguish "HAS-A" and "IS-A"

"Is-a" is a strictly defined in terms of sophisticated, meaning that a class is another class. The "HAS-A" is different, it represents a role with a certain responsibility.

A common reason that causes errors inheritance rather than synthesis / aggregation is the error of "HAS-A" as "IS-A".

E.g:

In fact, employees, managers, students describe a role, such as one person is "manager" inevitably "employee", another person may be "student employee", in the above design, one can not have more A role is "employee" that can no longer be "student", which is obviously unreasonable.

The error stems from the grade structure of "role" and "human" level structure, mistakenly put "HAS-A" as "IS-A". Solution:

Sixth, Dimit France (LOD)

Dimit France (Law of Demeter or short-handed LOD) is also a minimum knowledge principle (Least Knowledge Princi), that is, an object should be as little as possible for other objects.

Other expressions: Communication with your direct friends don't talk to "strangers", every software unit has only the least knowledge of other units, and is limited to software units closely related to this unit.

Dimit Fixation with Design Mode Facade Mode, Mediator Mode

Let the people ignorant the third chapter of "Laozi": "It is the rule of saints, the heart, it is true, the weak, and often makes people ignorant." Make the object "ignorance" In the "ignorant" state, it can reduce the cost of "rule". The so-called "minimum knowledge" principle, it is actually the rule of Laozi's "ignorance ignorance". Don't come to the "Laozi" cloud: "Small people are hoped, the neighboring countries are looking for, and the people of the chicken and dogs are smelling, and they are not coming." The object being ruled is separated, so that they have no direct communication. Can achieve differentiation of differentiation, and then the effect of treatment. Dimitfa is unspeakable with the rule of Laozi's "small country oligoma".

C # Design mode (4) -SIMPLE FACTORY PATTERN

Factory model is responsible for instantiating a large number of common interfaces. Factory model can dynamically decide which class instantiation, do not have to know which class is to be instantified each time. The factory model has the following forms:

Simple Factory Mode Factory Method (ABSTRACT FACTORY) mode

First, simple factory (Simple Factory) mode

The Simple Factory mode returns an instance of a class in several possible classes based on the data provided to it. Usually it returns a class having a common parent class and a public approach.

The Simple Factory mode is actually not a member of the GOF 23 design mode.

Second, Simple Factory mode role and structure:

Factory Role Creator (LightsImpleFactory): Factory class Create a product object under direct control of the client (Create method). Abstract Product Role Product (Light): Defines the parent class of the object created by the simple factory or the interface they share. Can be a class, abstract class or interface. Specific product role ConcreteProduct (Bulblight, Tubelight): Defines the object of the factory's specific processing.

Third, the program example:

Using

System;

public

Abstract

Class

Light

{Public abstract void turnon (); public abstract void turnoff ();

public

Class

Bulblight: Light

{Public override void () {Console.WriteLine ("bulb light is turned on");} public override void turnoff () {console.writeline ("bulb light is turned off";}}

public

Class

Tubelight: Light

{Public override void turnon () {Console.WriteLine ("Tube Light IS Turned ON");} PUBLIC OVERRIDE VOID Turnoff () {Console.WriteLine ("Tube Light IS Turned Off";}}

public

Class

LightsImpleFactory

{Public light version (String LightType) {if (LightType == "BULB") Return New Bulblight (); Else IF (LightType == "Tube") Return New Tubelight (); Else Return Null;}} PUBLIC

Class

Client

{Public static void main () {LightSimpleFactory LSF = new LightSimpleFactory (); Light L = lsf.create ("bulb"); l.Turnon (); l.Turnoff (); console.writeline ("--- ------------ "); l = lsf.create (" tube "); l.turnon (); l.Turnoff ();}}

Fourth, Simple Factory mode evolution

Simple Factory mode evolution (1)

In addition to the above usage, in some cases SIMPLE FACTORY can be played by an abstract product role, an abstract product class is also a subsidiary factory.

Program example:

Using

System;

public

Class

Light

{Public virtual void TurnOn () {} public virtual void TurnOff () {} public static Light Create (string LightType) {if (LightType == "Bulb") return new BulbLight (); else if (LightType == "Tube" Return new Tubelight (); else return null;}}

public

Class

Bulblight: Light

{Public override void () {Console.WriteLine ("bulb light is turned on");} public override void turnoff () {console.writeline ("bulb light is turned off";}}

public

Class

Tubelight: Light

{Public override void turnon () {Console.WriteLine ("Tube Light IS Turned ON");} PUBLIC OVERRIDE VOID Turnoff () {Console.WriteLine ("Tube Light IS Turned Off";}}

public

Class

Client

{Public static void main () {light l = light.create ("bulb"); l.turnon (); l.Turnoff (); console.writeline ("----------- ---- "); l = light.create (" tube "); l.Turnon (); l.Turnoff ();}} simple factory modification (2)

All three roles merged:

Near single mode (Singleton), it is different.

V. Advantages and Disadvantages:

Advantages: The factory class contains the necessary judgment logic, which can determine which product class is created, and the client can exempt the responsibility of directly creating product objects, but only "consumption" products. Simple factory model achieves the separation of responsibility through this practice.

Disadvantages: When the product has a complex multi-layer hierarchy, the factory class only has itself, and it is not changed, it is the shortcomings of the model. Because the factory class has concentrated all products to create logic, once it is not working properly, the entire system will be affected.

At the same time, the system expansion is difficult. Once add new products have to modify plant logic, it is possible that the plant logic is too complicated.

In addition, simple factory models typically use static factory methods, which makes it unable to inherit from subclasses, causing factory roles that cannot form a level structure based on inheritance.

C # Design mode (5) -Factory method Pattern

I. Factory Method mode

FactoryMethod mode is the creation mode of the class, which is intended to define a factory interface that creates a product object and delays the actual creation work into the subclass.

The factory method model is a further abstract and promotion of simple factory models. Due to the use of polymorphism, the factory method model maintains the advantages of simple factory models, and overcomes its shortcomings.

In the factory method mode, the core factory class is no longer responsible for the creation of all products, but to give the specific creation work to the subclass. This core class is only responsible for giving the interface that the specific factory must implement, without contacting which product class is instantiated. This allows factory method patterns to allow the system to introduce new products without modifying plant roles.

In Factory Method mode, factory class and product classes often have parallel level structures, and they correspond to one by one.

Second, Factory Method mode role and structure:

Abstract Factory Role: It is the core of the factory method model and is not related to the application. Any factory class for objects created in the mode must implement this interface.

Concrete Creator Role: This is a specific factory class that implements abstract factory interfaces, which contains closely related to applications, and is subject to application calls to create product objects. There are two such roles in the above figure: Bulbcreator and Tubecreator.

Abstract Product Role: The super-type of the object created by the factory method mode, that is, the common parent class of the product object or the joint owned interface. In the above figure, this role is Light.

Concrete Product Role: This role implements an interface defined by an abstract product role. A specific product has a special specific factory creation, and between them often correspond to one.

Third, the program example:

Using

System;

public

Abstract

Class

Light

{Public abstract void turnon (); public abstract void turnoff ();

public

Class

Bulblight: Light

{Public override void () {Console.WriteLine ("bulb light is turned on");} public override void turnoff () {console.writeline ("bulb light is turned off";}}

public

Class

Tubelight: Light

{Public override void turnon () {Console.WriteLine ("Tube Light IS Turned ON");} PUBLIC OVERRIDE VOID Turnoff () {Console.WriteLine ("Tube Light IS Turned Off";}}

public

Abstract

Class

Creator

{Public abstract light fact factory ();

public

Class

Bulbcreator: Creator: CREATOR

{Public override light factory () {return new bulblight ();}}

public

Class

Tubecreator: CREATOR

{Public override light factory () {return new tubelight ();}}

public

Class

Client

{CREATOR C1 = New Bulbcreator (); Creator C2 = New Tubecreator (); Light L1 = C1.FACTORY (); Light L2 = C2.Factory (); l1.turnon (); l1. "---------------"); l2.turnon (); l2.turnoff ();}}

Factory method activity sequence diagram

The activity process includes:

The client creates a BulbCreator object, and the client holds this object is Creator, and the actual type is Bulbcreator. The client then calls the Bulbcreator's Factory method, and then Bulbcreator calls Bulblight's constructor creates a product Bulblight object.

Fourth, factory method model and simple factory model

Factory method model is not very obvious with simple factory model re-structure. The core of the factory method is an abstract factory class, while simple factory model puts the core in a specific class.

Factory method model has an aliasing polymorphic factory model because the specific factory class has a common interface, or a common abstract parent class.

When the system extension needs to add a new product object, just add a specific object and a specific factory object, the original factory object does not need to make any modifications, nor does it need to modify the client, which is very good to meet "Open-Closed" in principle. Simple factory model has to modify the factory method after adding new product objects, and the extensibility is not good.

After the plant method mode is degraded, it can evolve into a simple factory model.

Five, Factory Method mode evolution

Using an interface or abstract class abstract factory role and abstract field frequency role can be implemented by an interface or abstract class. The use of multiple factory methods Abstract factory roles can specify more than one factory approach to enable specific factory roles to provide different factory methods, which can provide different business logic to meet the tasks of providing different product objects.

The cycle of the product uses factory methods to always call the product class constructor to create a new product instance and then provide this instance to the client. In the actual situation, the fact that the factory method does can be quite complicated.

A common complex logic is cycling using product objects. Factory objects will register the products that have been created into a gather, and then query the aggregated query according to the product status requested by the customer. If there is a product object that meets the requirements, return the product directly; if you don't have such a product object, create a new product object, then register this object into the gathering, then return to the customer end. "Flyweight Pattern" is like this.

The loss of polymorphism and the degenerate degradation of a factory method model depends on the polymorphism of factory role and product role. In some cases, this mode can be degraded.

The type returned by the factory method should be an abstract type, not a specific type. Clients calling factory methods should rely on abstract product programming, not specific products. If the factory only returns a specific product object, it violates the intention of the factory method, degrading, and it is no longer the factory model.

Factory level structure: factory objects should have an abstract super-type. If there is only one specific factory class in the level structure, the abstract factory can omit and degrade.

6. Relationship between Factory Method mode and other modes

The model related to the factory method mode also includes: template mode, MVC mode, enjoys, memo mode

Seven, another example

//

Factory Method Pattern - Real World EXAMPLE

Using

System;

Using

System.collections;

//

Product "

Abstract

Class

Page

{}

//

"Concreteproduct"

Class

Skillspage: Page

{}

//

"Concreteproduct"

Class

EducationPage: Page

{}

//

"Concreteproduct"

Class

ExperiencePage: Page

{}

//

"Concreteproduct"

Class

IntroductionPage: Page

{}

//

"Concreteproduct"

Class

Resultspage: Page: Page

{}

//

"Concreteproduct"

Class

ConclusionPage: Page: Page

{}

//

"Concreteproduct"

Class

Summarypage: Page

{}

//

"Concreteproduct"

Class

Bibliography: Page

{}

//

"Creator"

Abstract

Class

Document

{// Fields protected ArrayList pages = new ArrayList (); // Constructor public Document () {this.CreatePages ();} // Properties public ArrayList Pages {get {return pages;}} // Factory Method abstract public void CreatePages ();

Concretecreator

Class

Resume: Document

{/ Factory Method Implementation Override Public Void CreatePages () {pages.add (new skillspage ()); pages.add ());}}

//

Concretecreator

Class

Report: Document

{// Factory Method implementation override public void CreatePages () {pages.Add (new IntroductionPage ()); pages.Add (new ResultsPage ()); pages.Add (new ConclusionPage ()); pages.Add (new SummaryPage ( )));

/ ** /

///

/// FactoryMethodApp test ///

Class

FactoryMethodApp

{Public static void main (string [] args) {document [] DOCS = new document [2]; // Note: Constructors call factory method DOCS [0] = new resume (); DOCS [1] = new report () ; // display document pages foreach (document document in docs) {console.writeline (" Document " ------- ") Console.Writeline (" Page);}}}

C # Design mode (6) -Abstract factory Pattern

First, abstract factory (Abstract Factory) mode

Abstract factory model is the most abstract and most general form of all forms of factory models.

In order to facilitate the introduction of abstract factory models, introduce a new concept: Product Family. The so-called product family refers to a family that is located in different product level structures and functions. Figure:

There are four products in the figure, which are distributed in three different product level structures. Just indicate that the product family in a product and its level structure are to be specified, this product can be unique.

Introducing abstract factory model

The so-called abstract factory refers to all objects of a plant level structure that can create a product family that belongs to different product levels. If you are described by the figure, as shown below: Second, the structure of the Abstract Factory mode:

The things described in the figure are described below:

Abstract Factory Role: The role is the core of the factory method model, which is unrelated to the business logic of the application system.

Concent Factory Role: This role creates an instance of a product directly under the call. This role contains the logic of the appropriate product object, and this logic is closely related to the commercial logic of the application system.

Abstract Product (ABSTRACT Product) Role: The class of this role is the parent class of the object created by the factory method mode, or the interface they share.

Concrete Product Role: Any product object created by abstract factory modes is an example of a specific product class. This is something that the client is ultimately needed, and it must be full of commercial logic of the application system.

Third, the program example:

The program demonstrates the structure of an abstract factory that does not have any actual value.

//

Abstract Factory Pattern - Structural Example

Using

System;

//

"AbstractFactory"

Abstract

Class

AbstractFactory

{// Methods Abstract Public AbstractProducta CreateProducta (); Abstract Public AbstractProductB CreateProductB ();

//

"ConcreteFactory1"

Class

Concretefactory1: AbstractFactory

{// Methods Override Public AbstractProducta CreateProducta () {Return New ProductB () Override Public AbstractProductB CreateProductB () {Return New ProductB1 ();}}

//

"ConcreteFactory2"

Class

Concretefactory2: AbstractFactory

{// Methods Override Public AbstractProducta CreateProducta () {Return New ProductB () Override Public AbstractProductB CreateProductB () {Return New ProductB2 ();}}

//

"AbstractProducta"

Abstract

Class

AbstractProducta

{}

//

"AbstractProductB"

Abstract

Class

AbstractProductB

{// Methods Abstract Public Void Interact (AbstractProducta A);}

//

ProductA1 "

Class

ProductA1: AbstractProducta

{}

//

ProductB1

Class

ProductB1: AbstractProductB

{//Methods Override public void interact (AbstractProducta a) {console.writeline (this "interacts with" a);}} //

ProductA2

Class

Producta2: AbstractProducta

{}

//

ProductB2

Class

ProductB2: AbstractProductB

{// Methods Override public void interact (AbstractProducta a) {console.writeline (this "interacts with" a);}}

//

"Client" - The Intertion Environment of the Products - THE PRODUCTS

Class

ENVIRONMENT

{// Fields private AbstractProductA AbstractProductA; private AbstractProductB AbstractProductB; // Constructors public Environment (AbstractFactory factory) {AbstractProductB = factory.CreateProductB (); AbstractProductA = factory.CreateProductA ();} // Methods public void Run () {AbstractProductB. Interact (AbstractProducta);}}

/ ** /

///

/// ClientApp test environment ///

Class

ClientApp

{Public static void Main (string [] args) {AbstractFactory factory1 = new ConcreteFactory1 (); Environment e1 = new Environment (factory1); e1.Run (); AbstractFactory factory2 = new ConcreteFactory2 (); Environment e2 = new Environment (factory2 ); E2.Run ();}}

Fourth, use abstract factory model in what case:

In the following cases, you should consider using abstract factory modes:

A system should not depend on how the product instance is created, combined, and expressed, which is important for factory models of all forms. This system has more than one product family, and the system only consumes one of the product. It is used with products that belong to the same product family, which must be reflected in the design of the system. The system provides a library of a product class, all products appear in the same interface, so that the client does not rely on implementation.

Five, the origin of the abstract factory

It is said that the earliest application is used to create systems that can be operated in a window environment of different operating systems. For example, in Windows and UNIX systems have a window environment, in each operating system, there is a component family consisting of window components. We can give a functional description by an abstract role, and the specific subclass gives specific implementations under different operating systems, as shown:

It can be found that there are two product grade structures in the product classes, which are Button and Text; at the same time, there are two product families: UNIX product family and Windows product family. The system's creation requirements for product objects are satisfied by a plant level structure. There are two specific factory characters, namely UnixFactory and WinFactory. The UnixFactory object is responsible for creating products in the UNIX product family, while WinFactory is responsible for creating products in a Windows product family.

It is apparent that a system can only run in a window environment of an operating system without running on different operating systems. Therefore, the system can actually consume products that belong to the same product family.

In modern applications, the scope of use of abstract factory model has been greatly expanded, no longer asking the system to consume one product family.

6. Implementation in the ABSTRACT FACTORY mode in the actual system

Herbivore: Herbal animal Carnivore: Carnivore Bison: ['Baisn], American or European Bison

The actual code demonstrates an abstract factory that creates different animals in a computer game. Although animal species under different mainland are different, the relationship between the animals remains.

//

Abstract Factory Pattern - Real World EXAMPLE

Using

System;

//

"AbstractFactory"

Abstract

Class

ContinentFactory

{// Methods Abstract Public Herbivore CreateHerbivore (); Abstract Public Carnivore CreateCarnivore ();

//

"ConcreteFactory1"

Class

AfricaFactory: ContinentFactory

{// Methods Override public herbivore createherbivore () {Return New WildeBeest ();} {return new lion ();}}

//

"ConcreteFactory2"

Class

Americafactory: ContinentFactory

{//Methods override public herbivore creteherbivore () {return new bison ();} Override public carnivore createcarnivore () {return new wolf ();}}

//

"AbstractProducta"

Abstract

Class

Herbivore

{}

//

"AbstractProductB"

Abstract

Class

Carnivore

{// Methods Abstract Public Void Eat (Herbivore H);

//

ProductA1 "

Class

Wildebeest: Herbivore

{}

//

ProductB1

Class

Lion: Carnivore

{// Methods Override Public Void Eat (Herbivore H) {// Eat Wildebeest Console.writeline (this "EATS" H);}}

//

ProductA2

Class

Bison: Herbivore

{}

//

ProductB2

Class

Wolf: carnivore

{// Methods Override Public Void Eat (Herbivore H) {// Eat Bison Console.WriteLine (this "EATS" H);}}

//

"Client"

Class

Animalworld

{// Fields private Herbivore herbivore; private Carnivore carnivore; // Constructors public AnimalWorld (ContinentFactory factory) {carnivore = factory.CreateCarnivore (); herbivore = factory.CreateHerbivore ();} // Methods public void RunFoodChain () {carnivore. Eat (Herbivore);}}

/ ** /

///

/// GameApp Test class ///

Class

GameApp

{Public static void Main (string [] args) {// Create and run the Africa animal world ContinentFactory africa = new AfricaFactory (); AnimalWorld world = new AnimalWorld (africa); world.RunFoodChain (); // Create and run the America Animal World ContinentFactory America = new AmericafaFactory (); World = New Animalworld (America); World.Runfoodchain ();}}

Another example of an abstract factory:

How to design abstract factory for staying.

Seven, "Open-Closed" principle

"Open-Closed" principle requires the system to open open and enclose the modification. The purpose of enhancing its function is achieved by expanding. For systems involving multiple product families and multiple product levels, their functional enhancements include two aspects:

Increase product: Abstract Factory is very good to support the "open-closed" principle.

Add a level structure of new products: You need to modify all factory characters, not well supporting "Open-Closed" principles.

Combining, abstract factory model supports increasing new products in a slope manner, which is convenient for the increase in the new product family, and does not provide this convenience for the increase in new product rating.

C # Design mode (7) -singleton pattern

First, single example (Singleton) mode

Single example mode features:

Single examples can only have an instance. Single cases must create their own unique instances yourself. Single examples must provide this example to all other objects.

Single example mode application:

Each computer can have several printers, but there can be only one Printer Spooler, avoiding two print jobs simultaneously to the printer. A table with an automatic number primary key can have multiple users simultaneously, but there can only be one local allocation next primary key number in the database. Otherwise the primary key will appear.

Second, the structure of the Singleton mode:

The role that the Singleton mode contains only one, that is, Singleton. Singlet has a private constructor that makes it possible to instance it can be instances through the New New. In addition, this mode includes a static private member variable instance (). The Instance method is responsible for verifying and instantibration, then stores in a static member variable to ensure that only one instance is created. (About thread problems and Singleton unique to C # will be discussed in detail later).

Third, the program example:

The program demonstrates the structure of Singleton, which does not have any actual value.

//

Singleton Pattern - Structureral Example

Using

System;

//

"Singleton"

Class

Singleton

{// Fields private static Singleton instance; // Constructor protected Singleton () {} // Methods public static Singleton Instance () {// Uses "Lazy initialization" if (instance == null) instance = new Singleton (); return }}

/ ** /

///

/// Client Test ///

public

Class

Client

{Public static void main () {// constructor is protected - canNot Use new singleleton s1 = singleton.instance (); Singleton S2 = Singleton.instance (); if (S1 == S2) Console.Writeline ("The Same Instance ");}}

Fourth, in what case uses single example mode:

There is a necessary condition using the Singleton mode: single case mode should only be used when a system requires only one instance of a class. Conversely, if a class can coexist, do not use a single case mode.

note:

Do not use a single case mode to access global variables. This violates the intention of single example mode, preferably in a static member of the corresponding class.

Do not make a database connection, because a system may have multiple connections to the database, and if there is a connection pool, you should release the connection as much as possible. Singleton mode may cause resources to be released in time due to the use of static member storage class instances.

V. Implementation in Singleton mode in actual system

The Singleton code below demonstrates the load balancing object. In the load balancing model, there are multiple servers available services, and the task splitter randomly selects a server to ensure task equilibrium (actual situation is more complex than this). Here, the task assignment instance can only be one, which is responsible for picking the server and assigns tasks.

//

Singleton Pattern - Real World EXAMPLE

Using

System;

Using

System.collections;

Using

System.Threading;

//

"Singleton"

Class

Loadbalancer

{// Fields private static LoadBalancer balancer; private ArrayList servers = new ArrayList (); private Random random = new Random (); // Constructors (protected) protected LoadBalancer () {// List of available servers servers.Add ( "ServerI "); Servers.Add (" Serverii "); Servers.Add (" Serveriiii "); Servers.Add (" Serveriv "); Servers.Add (" Serverv ");} // methods public static loadbalancer getloadbalancer () { // Support multithreaded applications through // "Double checked locking" pattern which avoids // locking every time the method is invoked if (balancer == null) {// Only one thread can obtain a mutex Mutex mutex = new Mutex (); Mutex.waitone (); if (balancer == null) Balancer = new loadbalancer (); mutex.close ();} Return Balancer;} // Properties Public String Server {Get {// Simple, But Effective Random Load Balancer Int R = random.next (servers.count); Return Servers [R] .ToString ();}}} / ** /

///

/// SingletonApp test /// ////

public

Class

SingletonApp

{Public static void Main (string [] args) {LoadBalancer b1 = LoadBalancer.GetLoadBalancer (); LoadBalancer b2 = LoadBalancer.GetLoadBalancer (); LoadBalancer b3 = LoadBalancer.GetLoadBalancer (); LoadBalancer b4 = LoadBalancer.GetLoadBalancer (); // Same Instance? IF ((b1 == b2) && (b2 == b3) && (b3 == b4)) Console.Writeline ("Same Instance"); // do the load balancing console.writeline (b1.server) Console.writeline (b2.server); console.writeline (b3.server); console.writeLine (b4.server);}}} 6, C # Singleton mode in C #

The unique language characteristic of C # determines the unique way C # has a unique way to implement the Singleton mode. The reasons will not be described here, given several results:

method one:

Below is the code that implements the Singleton mode using the .NET Framework platform advantage:

SeaD

Class

Singleton

{Private singleton (); public static readonly singleton instance = new singleleton ();

This reduces the code, and also solves the performance loss of thread problems. So how do it work?

Note that the Singleton class is declared as Sealed to ensure that it will not be inherited, followed by the instance method, turn the original _instance member variable into public readonly, and is initialized during declaration. Through these changes, we really got the Singleton mode, because during the JIT processing, if the Static property in the class is used in any method, .NET Framework will initialize this property, so that the initialization instance property is initialized Singleton class instance is created and loaded. The private constructor and readonly (read only) guarantees that Singleton will not be instantiated again, which is the intention of the Singleton design mode. (Excerpted from: http://www.cnblogs.com/huqingyu/archive/2004/07/09/22721.aspx)

However, this also brings some problems, such as unable to inherit, the instance is initialized in the operation, and the delay initialization cannot be realized.

Details can refer to Microsoft MSDN article: "Exploring The Singleton Design Pattern"

Method Two:

Since there is a problem, we have other methods.

public

SeaD

Class

Singleton

{Singleton () {} public static Singleton GetInstance () {return Nested.instance;} class Nested {// Explicit static constructor to tell C # compiler // not to mark type as beforefieldinit static Nested () {} internal static readonly Singleton instance = New Singleton ();} This implements delayed initialization, and has many advantages, of course there are some shortcomings. For details, please visit: "Implementing The Singleton Pattern In C #". The article contains five Singleton implementations, in many aspects such as mode, thread, efficiency, and delayed initialization.

C # Design mode (8) -builder pattern

I. Builder mode

The builder mode can divide the internal representation of a product to the generation process of the product, so that a construction process can generate a product object with different internal appearances.

Construction of object properties

In some cases, an object will have some important nature, and the object cannot be used as a complete product before they don't have the right value. For example, an email has a sender address, recipient address, a subject, content, appendix, and other parts, and this email cannot be issued before the at least be assigned.

In some cases, some of an object must be assigned in a certain order. Another nature cannot be assigned before a nature is not assigned. These situations make the nature itself involves complex business logic.

At this time, this object is equivalent to a product to be built, while these properties of these properties are equivalent to the parts of the product, and the process of building a product is the process of combining parts. Since the process of combined parts is very complicated, these "parts" combination processes are often "externalized" to a target called builder, and the builder returns to the client is a product object that is completed all parts.

Named consideration

The reason why the "builder" is used without using "builder" is because of the production of parts, "construction" is more appropriate, "created" or "generated" is not appropriate.

Second, the structure of the Singleton mode:

Builder Role: Give an abstract interface to standardize the construction of the various components of the product object. In general, this interface is independent of the application's business logic. Creating a product object directly in the mode is a Concretebuilder role. The specific builder class must implement the method required for this interface: one is a construction method, and the other is the result returns.

Concrete Builder Role: The role is a class that is closely related to the application, which creates a product instance under application calls. This role is mainly completed, including:

Implement the interface provided by the Builder role, step by step to complete the process of creating a product instance. After the construction process is completed, an example of the product is provided.

The Director Role: The class call for this role is called the specific builder role to create a product object. The director does not have a specific knowledge of the product class, and the specific construction of the product is the specific constructor object.

Product (PRODUCT) Role: The product is a complex object in the construction.

The instructor role is the role of the client deal. The director role divides the client to create a product to the construction request for each part, and then delegate these requests to the specific builder role. The specific builder role is to do specific construction, but not known for the client.

Third, the program example:

The program demonstrates the process of completing component complex products step by step by step. Users can control the generation process and generate different objects.

//

Builder Pattern - Structural Example

Using

System;

Using

System.collections;

//

"Director"

Class

Director

{// Methods Public Void Construct (Builder Builder) {Builder.buildparta (); Builder.BuildpartB ();}}

//

"Builder"

Abstract

Class

Builder

{// Methods Abstract Public Void BuildParta (); Abstract Public Void BuildpartB (); Abstract Public Product getResult ();

//

"Concretebuilder1"

Class

Concretebuilder1: Builder

{// Fields private Product product; // Methods override public void BuildPartA () {product = new Product (); product.Add ( "PartA");} override public void BuildPartB () {product.Add ( "PartB") } Override public product getResult () {return products;}}

//

"Concretebuilder2"

Class

Concretebuilder2: Builder

{// Fields private Product product; // Methods override public void BuildPartA () {product = new Product (); product.Add ( "PartX");} override public void BuildPartB () {product.Add ( "PartY") } Override public product getResult () {return products;}}

//

Product "

Class

PRODUCT

{// Fields ArrayList Parts = New ArrayList (); // Methods Public Void Add (String Part) {Parts.Add (Part);} public void show () {Console.writeline ("Product Parts ---------------- - "); FOREACH (String Part in Parts) console.writeline (part);}

/ ** /

///

/// Client Test ///

public

Class

Client

{Public static void Main (string [] args) {// Create director and builders Director director = new Director (); Builder b1 = new ConcreteBuilder1 (); Builder b2 = new ConcreteBuilder2 (); // Construct two products director.Construct (B1); Product p1 = b1.getResult (); p1.show (); Director.Construct (b2); Product P2 = b2.getResult (); p2.show ();}} four, builder mode activities sequence:

The client is responsible for creating instructor and concrete builder objects. Then, the customer hand over the specific builder object to the instructor. Under the customer, the instructor manipulates the builder to start to create a product. When the product is created, the builder returns the product to the client.

V. Implementation of the builder mode:

The following program code demonstrates the SHOP object to use VehicleBuilders to build different vehicles. This example uses the different parts of the Builder mode sequence to build a vehicle.

//

Builder Pattern - Real World EXAMPLE

Using

System;

Using

System.collections;

//

"Director"

Class

SHOP

{// Methods public void Construct (VehicleBuilder vehicleBuilder) {vehicleBuilder.BuildFrame (); vehicleBuilder.BuildEngine (); vehicleBuilder.BuildWheels (); vehicleBuilder.BuildDoors ();}}

//

"Builder"

Abstract

Class

VEHICLEBUILDER

{// Fields protected Vehicle vehicle; // Properties public Vehicle Vehicle {get {return vehicle;}} // Methods abstract public void BuildFrame (); abstract public void BuildEngine (); abstract public void BuildWheels (); abstract public void BuildDoors ();

//

"Concretebuilder1"

Class

Motorcyclebuilder: Vehiclebuilder

{//Methods override public void buildframe () {vehicle = new vehicle ("motorcycle"); vehicle ["frame"] = "motorcycle frame";} Override public void buildngine () {vehicle ["engine"] = "500 CC ";} Override public void buildwheels () {vehicle [" wheeels "] =" 2 ";} Override public void builddoors () {vehicle [" doors "] =" 0 ";}} //

"Concretebuilder2"

Class

Carbuilder: Vehiclebuilder

{//Methods override public void buildframe () {vehicle = new vehicle ("car"); Vehicle ["frame"] = "car frame";} Override public void building "() {vehicle [" engine "] =" 2500 CC ";}} {vehicle [" wheeels "] =" 4 ";} Override public void builddoors () {vehicle [" doors "] =" 4 ";}}

//

"Concretebuilder3"

Class

Scooterbuilder: Vehiclebuilder

{// Methods Override Public Void BuildFrame () {VEHICLE = New Vehicle ("Scooter"); Vehicle ["frame"] = "scooter frame";} Override public void buildngine () {vehicle ["engine"] = "None "} Override public void buildwheels () {VEHICLE [" Wheels "] =" 2 ";} Override public void builddoors () {vehicle [" doors "] =" 0 ";}}

//

Product "

Class

Vehicle

{// Fields private string type; private Hashtable parts = new Hashtable (); // Constructors public Vehicle (string type) {this.type = type;} // Indexers public object this [string key] {get {return parts [ Key];} set {parts [key] = value;}} // methods public void show ("------------------- ------ "); console.writeline (" VEHICLE TYPE: TYPE); console.writeline ("frame:" parts ["frame"]); console.writeline ("Engine: Parts) "Engine"]); console.writeline ("#wheels:" Parts ["Wheels"]); console.writeline ("#DOORS:" Parts ["DOORS"]);}} / ** /

///

/// buildrapp test ///

public

Class

Builderapp

{Public static void Main (string [] args) {// Create shop and vehicle builders Shop shop = new Shop (); VehicleBuilder b1 = new ScooterBuilder (); VehicleBuilder b2 = new CarBuilder (); VehicleBuilder b3 = new MotorCycleBuilder () ; // construct and display vehicles Shop.construct (b1); b1.Vehi.show (); shop.construct (b2); b2.vehicle.show (); shop.construct (b3); b3.Vehi.show }}

Sixth, the evolution of the builder mode

The builder mode can evolve a variety of forms during use.

Abstract builder role

If you only need a specific builder in the system, you can omit the abstract builder. At this time, the code may be as follows:

//

"Director"

Class

Director

{Private concretebuilder builder; // methods public void construct () {builder.buildparta (); builder.buildpartb ();}}

Omit a guideliner role

In the case of only one of the specific builders, if the abstract builder role has been omitted, then the instructor role can be omitted. Let the Builder role play themselves their own double roles. At this time, the code may be as follows:

public

Class

Builder

{Private Product product = new Product (); public void BuildPartA () {// Some code here} public void BuildPartB () {// Some code here} public Product GetResult () {return product;} public void Construct () { At the same time, the client also needs to adjust the corresponding adjustments, as follows:

public

Class

Client

{Private Static Builder Builder; Public Static Void Main () {Builder = New Builder (); Builder.Construct (); Product Product = Builder.getResult ();}}

StringBuilder in C # is such an example.

Seven, in what circumstances use the builder mode

The following cases should be used to use the builder mode:

1. The product object that needs to be generated has a complex internal structure. 2. The properties of the product objects that need to be generated are interdependent, and the builder mode can be forced to generate the order. 3. Some other objects in the system are used during the object creation process, which are not easy to get in the creation of the product object.

The use of the builder mode mainly has the following effects:

1. The use of construction mode makes the internal representation of the product can be independent. Using the builder mode allows the client to do not know the details of the internal composition of the product. 2, each Builder is relatively independent, but independent of other Builder. 3, the final product built by the mode is easier to control.

C # Design mode (9) -Prototype Pattern

First, prototype mode

The use of prototype mode is: By giving a prototype object to specify the type of object to be created, then create more types of objects with a copy of this prototype object.

Talk from Sun Dasheng's means

Sun Wukong was in battle with Huang Feng, "Make a means of a body: put the macarre, smash it with mouth, look down, call the sound 'change', change hundreds of people, They are all kinds of dressing, each is holding a iron rod, strangely in the air. "In other words, Sun Wukong can copy a lot of" outside "according to their own image.

The means of old grandson is the prototype mode in the object-oriented design field.

C # supports prototype mode

In C #, we can easily achieve prototype mode through clone () methods. Any class, as long as you want to support clones, you must implement the iCloneable interface in C #. There is a clone method in the iCloneable interface that can be done in the class to copy a custom cloning method. There are two types of cloning: shallow copy and deep copy (Deep Copy).

(The NET Framework Design (Revised) ", Li Jianzhong translation) is a light copy is that the object referenced by the field is not copied when the field value of the object is copied. For example, if an object has a field pointing string, we make a shallow copy of the object, then two objects will reference the same string. And the deep copy is a way to copy objects referenced in the field reference in the object instance, so if an object has a field pointing to the string, we have a deep copy of the object, we will create a new one. Objects and a new string - new object will reference new strings. It should be noted that after performing a deep copy, the original object and the newly created object will not share anything; changing an object does not have any effect on another object. Second, the prototype mode structure:

Customer (Client) Role: Customer class presents a request for creating an object. Abstract prototype Role: This is an abstract role, usually implemented by a C # interface or abstract class. This role gives the interface required for the specific prototype class. In C #, abstract prototypes typically implements an Icloneable interface. Concrete Prototype Role: Copyable object. This role requires the interface required to achieve an abstract prototype role.

Third, the program example:

The following program gives a schematic implementation:

//

Prototype Pattern - Structural Example

Using

System;

//

Prototype

Abstract

Class

Prototype

{// Fields Private String ID; // Constructors public prototype (string id) {this.id = id;} public string id {get {return id;}} // methods abstract public prototype clone ();

//

"ConcretePrototype1"

Class

Concreteprototype1: prototype

{// Constructors Public ConcretePrototype1 (String ID): Base (ID) {} //Methods Override Public Prototype Clone () {// Shallow Copy Return (Prototype) this.memberwiseclone ();}}

//

"ConcretePrototype2"

Class

Concreteprototype2: prototype

{// Constructors Public ConcretePrototype2: Base (ID) {} //Methods Override Public Prototype Clone () {// Shallow Copy Return (Prototype) this.memberwiseclone ();}}

/ ** /

///

/// Client Test ///

Class

Client

{Public static void Main (string [] args) {// Create two instances and clone each ConcretePrototype1 p1 = new ConcretePrototype1 ( "I"); ConcretePrototype1 c1 = (ConcretePrototype1) p1.Clone (); Console.WriteLine ( "Cloned: {0} ", c1.id); ConcretePrototype2 P2 = New ConcretePrototype2 (" II "); ConcretePrototype2 C2 = (ConcretePrototype2) p2.clone (); console.writeline (" Cloney: {0} ", c2.id); This example implemented a shallow copy. The MEMBERWISECLONE () method is a protected method of the Object class that implements a shallow copy of the object. If you want to implement a deep copy, you should implement the iCloneable interface and write the clone interface method of Icloneable it yourself.

Fourth, prototype mode with prototype manager

The second form of prototype mode is the prototype mode of the original manager, and its UML map is as follows:

Customer (Client) Role: The client class proposes a request for an object to the prototype manager. Abstract prototype Role: This is an abstract role, usually implemented by a C # interface or abstract class. This role gives the interface required for the specific prototype class. In C #, abstract prototypes typically implements an Icloneable interface. Concrete Prototype Role: Copyable object. This role requires an interface required for an abstract prototype role. Prototype Manager Role: Create an object of a specific prototype class and record each of the created objects.

The following example demonstrates the color prototype stored in advance in the prototype manager, and the customer cloned the color object through the prototype manager.

//

Prototype Pattern - Real World Example

Using

System;

Using

System.collections;

//

Prototype

Abstract

Class

ColorPrototype

{// Methods Public Abstract ColorPrototype Clone ();

//

"Concreteprototype"

Class

Color: ColorPrototype

{// Fields Private Int Red, Green, Blue; // Constructors Public Color (Int Red, Int Green, Int Blue) {this.red = red; this.green = green; this.blue = blue;} //Methods public override ColorPrototype Clone () {// Creates a 'shallow copy' return (ColorPrototype) this.MemberwiseClone ();} public void Display () {Console.WriteLine ( "RGB values ​​are: {0}, {1}, { 2} ", red, green, blue;}} //

Prototype Manager

Class

ColorManager

{// Fields HashTable Colors = New HashTable (); // Indexers Public ColorPrototype This [String Name] {Get {Return (ColorPrototype) Colors [Name];} set {colors.add (name, value);}}}

/ ** /

///

/// prototypeApp test ///

Class

PrototypeApp

{Public static void main (string [] args) {ColorManager ColorManager = New ColorManager (); // Initialize with Standard ColorManager ["Red"] = New Color (255, 0, 0); ColorManager ["green"] = New Color (0, 255, 0); ColorManager ["Blue"] = New Color (0, 0, 255); // User Adds Personalized ColorManager ["angry"] = New Color (255, 54, 0); ColorManager ["Peace"] = New Color (128, 211, 128); ColorManager ["Flame"] = New Color (211, 34, 20); // User Uses SELECTED Colors String ColorName = "Red"; color C1 = (Color) .clone (); c1.display (); colorname = "peace"; color c2 = "color" color [colorname] .clone (); c2.display (); colorName = "flame" Color C3 = (color) ColorManager [ColorName] .clone (); c3.display ();}}

Five, shallow copy and deep copy

Two examples of shallow copies and deep copies are given below, and examples use the iCloneable interface. The arrays in the C # are referenced variables, and we demonstrate them through an array:

Shallow copy:

Using

System;

Class

ShallowCopy: Icloneable

{Public int [] v = {1,2,3}; public object clone () {return this.memberwiseclone ();} public void display () {foreach (int i in v) Console.write (i ", "); Console.writeline ();}}

Class

Client

{Public static void main () {shallowcopy sc1 = new shallowcopy (); shallowcopy sc2 = (shallowcopy) sc1.clone (); sc1.v [0] = 9; sc1.display (); sc2.display (); }

The ShallowCopy object implements a shallow copy, so when the SC1 is cloned, the field V is not cloned, which causes the field v of SC1 and SC2 to point to the same V, so when the SC1 is modified, the V [0] of SC1 is modified. V [0] of SC2 has also changed.

Deep copy:

Using

System;

Class

DeepCopy: Icloneable

{Public int [] v = {1, 2, 3}; // Default constructor public DeepCopy () {} // Provide private constructor for Clone method PRIVATE DeepCopy (int [] v) {this.v = INT []) v.clone ();} public object clone () {// constructs a new DeepCopy object, constructing the v retturn new deepcopy used in the original object;} public void Display () {Foreach (INT I IN V) Console.Write (i ","); console.writeline ();}}

Class

Client

{Public static void main () {DeepCopy DC1 = New DeepCopy (); deEPCopy DC2 = (DeepCopy) DC1.Clone (); DC1.V [0] = 9; dc1.display (); dc2.display (); }

This time, when cloning, not only cloned the object itself, even the array field inside and was cloned. Therefore, the final printing DC1 is different from DC2.

Sixth, Prototype mode advantages and disadvantages

The advantages of Prototype mode include

1, Prototype mode allows dynamic to increase or reduce product classes. Since the method of creating a product class instance is that there is an inside of the production batch, there is no impact on the entire structure. 2, Prototype mode provides a simplified creation structure. Factory method model often requires the same level structure as the product level structure, and Prototype mode does not need this. 3, Portotype mode has the ability to dynamically load new features to an application software. Due to the high independence of Prototype, it can easily load new features without affecting the old system. 4. The product class does not require any level of prior defined, because the Prototype mode is suitable for any level structure. Disadvantages of Prototype mode:

The most important disadvantage of Prototype mode is that every class must be equipped with a cloning method. Moreover, this cloning method needs to consider the function of the class, which is not very difficult for a new class, but when transforming the existing classes, it is not necessarily easy.

C # Design mode (10) -adapter pattern

Structural Pattern describes how to combine classes or objects together to form a larger structure. Structural mode describes two different things: examples and classes. According to this, structural mode can be divided into a structural mode of the class and the structure of the object.

Subsequent content will include the following structural modes:

Adapter mode (Adapter): Match interfaces of different classes combination mode (Composite): A tree structure of simple and composite objects decorative patterns (Decorator): Add responsibilities to objects dynamically proxy mode (Proxy): An object representing another object Flyweight (Flyweight): a Fine-grained Instance Used for Efficient Sharing Facade Mode (Facade): a Single Class That Renders An entire Subsystem Bridge mode (bridge): Separates An Object Interface from ITS IMPLEMentation

I. Adapter (Adapter) mode

The adapter mode converts a class interface into another interface that the client is expected, so that the original interface does not match two classes that work together can work together.

Origin of the name

This is very like a transformer (Adapter), and the transformer converts a voltage into another voltage. The US live electrical voltage is 110V, while China's voltage is 220V. If you want to use American electrical appliances in China, there must be a transformer that converts 220V voltage to 110V voltage. This transformer is an adapter.

Adapter mode is also like a packaging process of the goods: the true look of the packaged goods is masked and changed, so someone is called the wrapper mode. In fact, everyone often writes a lot of such Wrapper classes, putting some of the existing classes, making it possible to meet the needs of the need.

Two forms of adapter mode

The adapter mode has two types of adapter mode and object's adapter mode. We will discuss these two Adapter mode respectively.

Second, the structure of the Adapter mode:

As can be seen from the figure, the AdapteE class does not have a Request method, and the customer is looking forward to this method. In order to enable customers to use the Adaptee class, the Target interface is implemented, that is, the class Adapter class, the Adapter class implements the Target interface, and inherits from the Adaptee, the request method of the Adapter class re-encapsulates the adaptee's SpecificRequest method, and the purpose of the adaptation. Because Adapter and Adaptee are inherited relationships, this determines this adapter mode to be class.

The characters involved in this adapter mode include:

Target Role: This is the interface that customers expect. Because C # does not support multiple inheritance, the target must be an interface and cannot be a class. ADAPTEE Role: The class that needs to be adapted. Adapter Role: Convert the source interface into a target interface. This role must be class.

Third, the class of Adapter mode is schematically realized:

The following program gives a schematic implementation of a class of Adapter mode:

//

Class Adapter Pattern - Structureral Example

Using

System;

//

"Itarget"

Interface

ITarget

{// Methods void request ();

//

Adaptee

Class

Adaptee

{//Methods Public Void SpecificRequest () {Console.WriteLine ("Called SpecifRequest ()");}}

//

Adapter

Class

Adapter: Adaptee, Itarget

{// Implements Itarget Interface Public Void Request () {// Possibly Do Some Data Manipulation // andtes Call SpecificRequation THIS.SPECICIFICREQUEST ()}

/ ** /

///

/// Client Test ///

public

Class

Client

{Public static void main (string [] args) {// create adapter and place a request itarget t = new adapter (); t.Request ();}}

Fourth, the structure of the object's Adapter mode:

As can be seen from the figure: The client needs to call the Request method, and Adaptee does not have this method, in order to allow the client to use the Adaptee class, you need to provide a wrapper class Adapter. This packaging class wraps an example of Adaptee to connect the client with Adaptee. Since Adapter and Adaptee are delegated relationships, this determines this adapter mode to be object.

The characters involved in this adapter mode include:

Target Role: This is the interface that customers expect. The target can be a specific or abstract class or an interface. ADAPTEE Role: The class that needs to be adapted. Adapter Role: Convert the source interface into a target interface by an Adaptee object internally packaged (WRAP). 5. The Adapter mode of the object is schematically realized:

The following program gives a schematic implementation of a class of Adapter mode:

//

Adapter Pattern - Structureral Example

Using

System;

//

Target

Class

Target

{// Methods Virtual public void request () {// Normal Implementation Goes Here}}

//

Adapter

Class

Adapter: Target

{// Fields private Adaptee adaptee = new Adaptee (); // Methods override public void Request () {// Possibly do some data manipulation // and then call SpecificRequest adaptee.SpecificRequest ();}}

//

Adaptee

Class

Adaptee

{//Methods Public Void SpecificRequest () {Console.WriteLine ("Called SpecifRequest ()");}}

/ ** /

///

/// Client Test ///

public

Class

Client

{Public static void main (string [] args) {// create adapter and place a request target t = new adapter (); t.REQUEST ();}}

Sixth, in what circumstances use the adapter mode

Use adapter mode in the following cases:

1. The system needs to use an existing class, and this type of interface does not meet the needs of the system. 2. Want to build a class that can be reused, used for some classes that do not have much relatively related to each other, including some work that may be introduced in the future. These source categories do not have a very complex interface. 3. (For object adapter) In the design, you need to change the interface of multiple subclasses. If you use the adapter mode of the class, you should do an adapter for each subclass, which is not practical.

Seven, an example of an actual application adapter mode

The following program demonstrates the application of Class Adapter and Object Adapter.

//

EXAMPLE OF IMPLEMENTING THE ADAPTER PATTERN

Using

System;

//

Target

public

Interface

Icar

{Void drive ();

//

Direct Uses WITHOUT Adapter

public

Class

CTOYOTA: ICAR

{Public void drive () {console.writeLine ("Vroom Vroom, We're Off In Our Toyota);}}

//

Adaptee

Publicclass

Ccessna

{Public void fly () {Console.WriteLine ("Static Runup OK, We're Off In Our C172");}}

//

Class Adapter

public

Class

CDRIVABECESSNA: CCESSNA, ICAR

{Public void drive () {base.fly ();}}

//

Object Adapter

public

Class

CDRIVABECESSNA2: ICAR

{Private ccessna m_ocontained; public cdrivablecessna2 () {m_ocontained = new ccessna (); public void drive () {m_ocontained.fly ();}}

//

Client

public

Class

Client

{Public static void main (string [] args) {Icar = new ctoyota (); console.write ("Class Adapter: Driving An Automobile); OCAR.Drive (); OCAR = New CDRIVABECESSNA (); console.write ("Driving a Cessna"); OCAR.Drive (); OCAR = New CDRIVABECESSNA2 (); Console.write ("Object Adapter: Driving a Cessna); OCAR.Drive ();}}

Eight, discussions about Adapter mode

The Adapter mode has the following places that are worth noting in implementation:

1. The target interface can be omitted, and the mode is degraded. But this approach seems to be mediocrity and is not mediocre, which allows Adaptee to do not have to achieve unwanted methods (you can refer to the default adapter mode). Its expression is that the parent class implements the default method, while subclasses only need to achieve their own unique methods. This has some template mode. 2, the adapter class can be an abstract class. 3, adapter mode with parameters. With this approach, the adapter class can return a suitable instance to the client according to the parameters.

C # Design mode (11) -composite pattern

First, synthesis mode

Synthetic models are sometimes called part - a part-whole mode. Synthesis Mode The object is organized into the tree structure and can be used to describe the overall relationship between the overall and part. The synthesis pattern allows the client to treat simple elements with the composite element.

Talking from a monk story

This is a story of my grandmother: I have a mountain in the past, there is a temple in the mountains. There is an old monk in the temple to tell the story, what is the story? Once there was a mountain, there was a temple in the mountains ... How many times will my grandmother's story, depending on how long you are asleep. There is a mountain in the story, there is temple, there is monk, there is a story. Therefore, there are two roles of the story: there is no other role inside; there is another role inside.

Tree structure of the object

A tree structure consists of two nodes: branches nodes and leaves nodes. The branches can have a sub-node, and an leaves node cannot have a sub-node. In addition to the root node, other nodes are there and have only one parent node.

Note: A branch node may not bring any leaves, but it is still a branches node because there is a branch node because of the ability to bring leaves. A leaf node will never be with a child node. Second, the synthesis pattern overview

The class diagram shown below saves details of each role.

It can be seen that the above class diagram structure involves three characters:

Abstract Component Role: This is an abstract role that specifies an interface to participate in the combination. This role gives a common interface and its default behavior. Leaf member (LEAF) Role: Represents the leaves object participating in the combination. A leaf object does not have a lower grade object. A composite component (Composite) role: represents the object of the combined organic object and gives the behavior of the branches component object.

It can be seen that the object of the CompositeTe type can contain other objects of the Component type. In other words, the Composite type object may contain other branches or leaves (Leaf) types of objects.

The implementation of the synthesis mode is divided into two forms according to the distinction between the implemented interface, respectively, respectively, respectively, respectively. Synthesis Mode does not provide management methods for parent objects, but the synthesis mode must provide a management method for sub-object (such as: add, remove, getchild, etc.) in a suitable place.

Transparent way

As the first choice, declare all methods for managing subclass objects in Component, including add (), remove (), and getChild () methods. The advantage of doing this is that all components have the same interface. At the client, the difference between the leaves object and the synthetic object is lost at the interface level, and the client can treat all objects equally. This is the transparent form of synthesis pattern.

The disadvantage of this choice is not safe enough because the leaves objects and synthetic objects are essentially different. The leaves object cannot have the next level of object, so add (), remove (), and getChild () methods are meaningless, which is not wrong during the compilation period, but only in the run period.

Security mode

The second option is to declare all methods for managing subclass objects in the Composite class. Such a practice is a safe approach, because the object of the leaves does not have a method of managing sub-objects at all, so if the client uses these methods to the leaves object, the program is in the compilation period.

The disadvantage of this option is not transparent, because the leaves and synthetic classes will have different interfaces.

These two forms have advantages and disadvantages, and they need to make a decision according to the specific circumstances of the software.

Third, the structure of the safety format

Safety synthesis mode requires management aggregation only in the branches component, and does not appear in the leaf member.

This form involves three characters:

Abstract Components: This is an abstract role that defines a common interface and its default behavior to manage all child objects. In the security format synthesis mode, the component role is not a method of defining the management sub-object, which is given by the branches component object. Leaf member (LEAF) Role: The leaves object are objects with no lower scales, define the behavior of the original object to participate in the combination. A composite component (Composite) role: represents the object of the combined grade object. The tree object gives all the methods of managed objects, such as add (), remove (), getChild (), etc.. Fourth, the safety style synthetic model is realized

The following exemplary code demonstrates the security-style synthetic mode code:

//

Composite Pattern - Structural Example

Using

System;

Using

System.Text;

Using

System.collections;

//

"Component"

Abstract

Class

Component

{// Fields Protected String Name; // Constructors Public Component (String Name) {this.name = Name;} // Operation Public Abstract Void Display (int Depth);}

//

"Composite"

Class

Composite: Component

{// Fields private ArrayList children = new ArrayList (); // Constructors public Composite (string name): base (name) {} // Methods public void Add (Component component) {children.Add (component);} public void Remove (Component component) {children.Remove (component);} public override void Display (int depth) {Console.WriteLine (new String ( '-', depth) name); // Display each of the node's children foreach ( Component Component In Children Component.display (depth 2);}}

//

"Leaf"

Class

Leaf: Component

{// Constructors Public Leaf (String Name): Base (Name) {} //Methods Public Override Void Display (INT Depth) {Console.WriteLine (New String ('-', Depth) Name);}}

/ ** /

/// // Client Test ///

public

Class

Client

{Public static void main (String [] args) {// create a tree structure composite root = new composite ("root"); root.add (New Leaf ("Leaf A"); root.add (New Leaf "Leaf B")); Composite Comp = New Composite ("Composite X"); Comp.Add (New Leaf XA "); Comp.Add (New Leaf (" Leaf XB "); root.add (Comp); root.add (New Leaf ("Leaf C")); // add and remove a leaf leaf L = New Leaf ("Leaf D"); root.add (l); root.remove (L) ; // recursively display nodes root.display (1);}} 5, transparent synthetic mode structure

Different from the safety format mode, transparent synthetic mode requires all specific components, regardless of the branches and leaves, all in line with a fixed interface.

This form involves three characters:

Abstract Component Role: This is an abstract role that specifies an interface to a combination of objects to specify a common interface and default behavior. Leaf member (LEAF) Role: Represents a combined leaves object to define the behavior of the original object to participate in the combination. The leaves will give add (), remove (), and a mediocrity implementation of the method used to manage subclasses on objects. Tree branches (Composite) Role: Represents objects of participating combined organized objects, defining the behavior of such objects.

Six, transparent synthetic model implementation

The following exemplary code demonstrates the security-style synthetic mode code:

//

Composite Pattern - Structural Example

Using

System;

Using

System.Text;

Using

System.collections;

//

"Component"

Abstract

Class

Component

{// Fields protected string name; // Constructors public Component (string name) {this.name = name;} // Methods abstract public void Add (Component c); abstract public void Remove (Component c); abstract public void Display INT depth;

//

"Composite"

Class

Composite: Component

{// Fields private ArrayList children = new ArrayList (); // Constructors public Composite (string name): base (name) {} // Methods public override void Add (Component component) {children.Add (component);} public override void Remove (Component component) {children.Remove (component);} public override void Display (int depth) {Console.WriteLine (new String ( '-', depth) name); // Display each of the node's children FOREACH (Component Component In Children) Component.display (depth 2);}} //

"Leaf"

Class

Leaf: Component

{// Constructors Public Leaf (String Name): Base (Name) {} // Methods Public Override Void Add (Component C) {Console.Writeline ("Cannot Add to a Leaf");} Public Override Void Remove (Component C) ) {Console.Writeline;} public override void display (int Depth) {console.writeline (new string ('-', defth) name);}}

/ ** /

/// // Client Test ///

public

Class

Client

{Public static void main (String [] args) {// create a tree structure composite root = new composite ("root"); root.add (New Leaf ("Leaf A"); root.add (New Leaf "Leaf B")); Composite Comp = New Composite ("Composite X"); Comp.Add (New Leaf XA "); Comp.Add (New Leaf (" Leaf XB "); root.add (Comp); root.add (New Leaf ("Leaf C")); // add and remove a leaf leaf L = New Leaf ("Leaf D"); root.add (l); root.remove (L) ; // Recursively Display Nodes root.display (1);}}

7. Several questions considered when using synthetic models

Obviously give the reference to the parent object. The reference to the parent object is given to the child object, which can easily traverse all parent objects. With this reference, it can be convenient to apply the responsibility chain mode. In the usual system, the sharing of the component can be implemented using the enchant mode, but because the objects of the synthesis pattern often have references to the parent object, the sharing is not easy to implement. Sometimes the system needs to traverse a sub-component of a branches many times, at this time, it is conceivable to temporarily store the results of the middle of the middle of the child member as a cache. With regard to what data type to store sub-object, use ArrayList in the schematic code, and other aggregation or arrays can be used in the actual system. The client should do not directly call the method in the leaf class, but to complete the call with the polymorphism of its parent class, this can increase the reuse of the code. Eight, monk story

Nine, an example of a practical application Composite mode

Below is a procedure for practical applications that demonstrate the process of construct complex graphics trees by some basic image elements (line, gardens, etc.) and some composite image elements (composed of basic image elements).

//

Composite Pattern - Real World EXAMPLE

Using

System;

Using

System.collections;

//

"Component"

Abstract

Class

DrawingerElement

{// Fields Protected String Name; // Constructors Public DrawingeElement (String Name) {this.name = name;} // Operation Abstract Public Void Display (int indent);

//

"Leaf"

Class

PrimitiveElement: DrawingerElement: DrawingerElement

{// Constructors Public PrimitiveEleMent (String Name): Base (Name) {} // Operation Public Override Void Display (INTIONT) {Console.writeline (New String ('-', Indent) "Draw A {0}" Name);}}

//

"Composite"

Class

CompositeElement: DrawingeElement: DrawingerElement

{// Fields private ArrayList elements = new ArrayList (); // Constructors public CompositeElement (string name): base (name) {} // Methods public void Add (DrawingElement d) {elements.Add (d);} public void Remove (DrawingeElement D); PUBLIC OVERRIDE VOID DISPLAY (INTIONT) {Console.writeline (New String ('-', IND) " Name); // Display Each Child Element On this Node Foreach (DrawingerElement C in Elements) C. Display (Indenter 2);}} / ** /

/// // compositeapp test ////

public

Class

CompositeApp

{Public static void Main (string [] args) {// Create a tree structure CompositeElement root = new CompositeElement ( "Picture"); root.Add (new PrimitiveElement ( "Red Line")); root.Add (new PrimitiveElement ( "Blue circle"); root.add ("Green Box"); CompositeElement Comp = New CompositeElement ("Two Circles"); Comp.Add (New PrimitiveElement ("Black Circle"); Comp.Add (New PrimitiveElelement); root.add (comp); // add and remove a primitiveElelement PrimitiveEleMent L = New PrimitiveElement ("Yellow line"); root.add (l); root.remove (L) ; // Recursively Display Nodes root.display (1);}}

Synthetic models have contacted in many other modes and will gradually introduce in subsequent content.

转载请注明原文地址:https://www.9cbs.com/read-116431.html

New Post(0)