工厂方法模式

来源:互联网 发布:软件封装教程 编辑:程序博客网 时间:2024/05/17 22:37

一.定义: 工厂方法模式又称工厂模式,也叫虚拟构造器模式或者多台工厂(Polymorphic Factory)模式,属于类的创建型模式.在工厂模式中, 父类负责定义创建对象的公共借口,而子类则负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成,即由子类来决定研究竟应该实例化(创建)哪一个类.二.类和对象的关系: Product:产品角色   定义产品的接口. ConcreteProduct:真实的产品   实现接口Product的类 Creator:工厂角色   声明工厂方法(FactoryMethod),返回一个产品. ConcreteCreate:真实的工厂   实现FactoryMethod工厂方法,由客户调用,返回一个产品的实例.三.优势和缺陷 在工厂模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节.工厂方法模式的核心是一个抽象工厂类,各种具体工厂类通过   抽象工厂类将工厂方法继承下来.如此使得客户可以只关心抽象产品和抽象工厂,完全不用理会返回的是哪一种具体产品,也不关心它是如何被具体工厂创建的.  1.基于工厂角色和产品角色的多态性设计是工厂方法模式的关键.它能够使工厂可以自主确定创建和中产品对象,而如何穿件这个对象的细节则完全封装在具体工厂内部.   工厂方法模式之所以又被称为多态工厂模式,就正是因为所有的具体工厂类都具有同一抽象父类.

 2.使用工厂方法模式的另外一个优点是在系统中加入新的产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其他的具体工厂和具体产品,   而只要添加一个具体工厂和具体产品就可以了,这样,系统的可扩展性非常好.优秀的面向对象设计鼓励使用封存(Encapsulation)和委托(Delegation)来构造软件系统,   工厂方法模式正是使用了封装和委托的典型例子,其中封装是通过抽iang工厂来体现的,而委托则是通过抽象工厂将创建对象的责任完全交给具体工厂来体现的.

 3.使用抽象工厂方法模式的缺点是在添加新产品时,需要重新写一个具体产品类,而且还要提供与之对应的具体工厂类,当两者都比较简单时,系统会有相对额外的开销.四.应用情景 类不知道自己要创建哪一个对象. 类用它的子类来指定创建哪个对象. 客户需要清楚创建了哪一个对象.

五.例题:

using System;using System.Collections.Generic;using System.Text;using System.Collections;

namespace AbstractFactory {    public abstract class Page {            }    public abstract class Document {        protected ArrayList pages = new ArrayList();        public Document() {            this.CreatePages();        }        public ArrayList Pages {            get {                return pages;            }        }        abstract public void CreatePages();    }    public class SkillsPage : Page {

    }    public class EducationPage : Page {

    }    public class ExperiencePage : Page {

    }    public class IntroductionPage : Page {

    }    public class ResultsPage : Page {

    }    public class ConclusionPage : Page {

    }    public class SummaryPage : Page {

    }    public class BibliographyPage : Page {

    }    public class Resume : Document {        public override void CreatePages() {            pages.Add( new SkillsPage() );            pages.Add( new EducationPage() );            pages.Add( new ExperiencePage() );        }    }    public class Report : Document {        public override void CreatePages() {            pages.Add( new IntroductionPage() );            pages.Add( new ResultsPage() );            pages.Add( new ConclusionPage() );            pages.Add( new BibliographyPage() );        }    }    public class Test {        public static void Main() {            Document[] docs = new Document[ 2 ];            docs[ 0 ] = new Resume();            docs[ 1 ] = new Report();            foreach( Document docu in docs ) {                Console.WriteLine( "/n" + docu + "====" );                foreach( Page page in docu.Pages ) {                    Console.WriteLine( " " + page );                }            }

            Console.ReadLine();        }    }}