`

《深入浅出设计模式-中文版》读书笔记-工厂模式(五)

阅读更多

  今天给大家带来的是:工厂模式。

  我们在代码中创建一个对象,我们会很自然的想到new。其实,除了new意外,我们还有很多的方式可以创建对象。不说复杂的模式,就说简单的语法,其实.NET框架中还有下面的方法。根据需要创建的对象的类型,动态创建对象。

  

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->Activator.CreateInstance

 

  通过前面我们已经讲过一条原则:

  针对接口编程,不针对实现编程。

  使用new创建对象很明显就是一个针对实现编程,new后面需要一个具体的类,不允许你new一个接口或者是抽象类。包括用Activator.CreateInstance都不能创建接口或者抽象类。

  那是不是就是说以后不能或者是不要再用new了,都用其他方式吗?

  也不是的,也要根据情况来分析,不是一概而论的,在后面会给出一些简单的标准,更多的要结合具体的设计定夺。

  很多时候我们会碰到下面的代码:

  

代码
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->     string userType = "";
                
if (userType == "admin")
                {
//创建管理员
                }
                
else if (userType == "supervisor")
                {
//创建超级管理员
                }
                
else if (userType == "coommon")
                {
                    
//创建普通用户
                }

 

  如果以后增加了用户的类型,不仅要创建用户类型实体,还需要打开创建用户的这段代码,后面加上一个if。。。else。。。。

  如果这段代码没有封装,就更麻烦了,散落在项目的各处,每个地方都要打开,ctrl+c,ctrl+v。开始了无尽的噩梦。

  对于后面的维护成了问题,而且违反了一条原则:

   

  OCP原则,对增加开放,对修改封闭。

  首先使用封装变化原则对这段代码做一些抽象,上面这段明显是变化较多的地方,其他的代码可能是现实创建的用户的姓名之类的。变成一个方法,然后将用户类型定义为enum类型,减少调用者由于输入错误导致程序错误。

  

代码
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BeautyCode.DesignPattern.Head.First.Factory
{
    
public enum UserType
    {
        Admin,
        Supervisor,
        Common
    }
    
public abstract class User
    {
        
public virtual UserType UserType
        {
            
get;
            
protected set;
        }
        
public User(UserType userType)
        {
            UserType 
= userType;
        }
        
public virtual string Username
        {
            
get;
            
set;
        }
        
public virtual int Age
        {
            
get;
            
set;
        }
        
public virtual void DisplayName()
        {
            Console.WriteLine(
"my name is {0}, i'm {1} years old.", Username, Age);
        }
    }
    
public class AdminUser : User
    {
        
public AdminUser()
            : 
base(UserType.Admin)
        { }
    }
    
public class CommonUser : User
    {
        
public CommonUser()
            : 
base(UserType.Common)
        { }
    }
    
public class SupervisorUser : User
    {
        
public SupervisorUser()
            : 
base(UserType.Supervisor)
        {
        }
    }
}

 

  

代码
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BeautyCode.DesignPattern.Head.First.Factory
{
   
public  class UserFactory
    {
       
public static User CreateSingleUser(UserType userType)
       {
           User user 
= null;
           
switch (userType)
           {
               
case UserType.Admin :
                   user 
= new AdminUser(); 
                   
break;
               
case UserType.Common :
                   user 
= new CommonUser();
                   
break;
               
case  UserType.Supervisor :
                   user 
= new SupervisorUser();
                   
break;
               
default :
                   
break;
           }
           
return user;
       }
    }
}

 

  调用代码

 

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->Head.First.Factory.User user = Head.First.Factory.UserFactory.CreateSingleUser(Head.First.Factory.UserType.Admin);

 

  以后增加新的用户类型就不用在各处修改了,只要新建一个类型实体,然后打开工厂方法,修改一下就可以了。

  有没有更好的呢?

  能否只是增加一个用户类型实体类呢?

  答案是:能

 

  修改一下工厂方法,利用泛型和Activator

  

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> public static T CreateSingleUser2<T>() where T:User
       {
           T user 
= null;
           user 
= Activator.CreateInstance<T>();
           
return user;
       }

 

  调用者的代码修改为

  

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> Head.First.Factory.User user1 = Head.First.Factory.UserFactory.CreateSingleUser2<Head.First.Factory.AdminUser>();

 

  有没有更好的呢?

  期待大家的参与讨论!!!!

  其实我这个还不算是真正意义上的工厂模式,顶多算是个简单的工厂,后面我会补充一些更好的例子。

  感谢大家耐心看完本篇博文。

  定义

  工厂模式:定义了一个创建对象的借口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到了子类。

   上面的描述中提到了“子类决定”的决定,希望不要错误理解,不是模式允许子类本身在运行的时候做决定,而是指在编写创建者类的时候,不需要知道实际创建的类是哪一个。调用者选择使用哪个类,自然就决定了实际创建的对象。

分享到:
评论

相关推荐

    设计模式+UML.rar

    包含以下文件: Java设计模式-图解-附代码.pdf 从Java类库看设计模式.doc 六大UML类图关系.docx 认识UML类图元素_java之UML.doc 设计模式6大原则.doc 设计模式学习笔记.doc 深入浅出设计模式(中文版).pdf

    Java设计模式教程

    该资料介绍Java各类开发模式,包含以下教程:《深入浅出设计模式(中文版)》《Java单例模式》《Java设计模式-图解-附代码》《JAVA设计模式之单例模式(完整版)》《Java学习笔记(必看经典)》《Java总复习》《单例模式》...

    Head First 设计模式 扫描版

    这本书以其独特的视觉风格和易于理解的教学方法,深入浅出地介绍了设计模式这一复杂的主题。设计模式是软件工程中经过实践验证的解决方案,用于解决在面向对象设计中常见的问题。 本书包含23种经典的设计模式,这些...

    Java设计模式第2版中文版.rar

    总之,《Java设计模式第2版中文版》是一本涵盖全面、深入浅出的教程,无论是初学者还是经验丰富的开发者,都能从中受益。通过学习这本书,你可以提升自己的编程思维,写出更优雅、更健壮的代码,为团队协作和项目...

    <<MFC深入浅出>>(中文简体)

    "读书拉.htm"可能是书中的一些笔记或阅读指南,"深入浅出 MFC_华中理 工_简体版.pdf"是主要的教材内容,"dushula.txt"可能是读者在阅读过程中的个人感悟或摘录,这些资源结合起来,将构成一个全面的MFC学习资料库。...

    包括JAVA夜未眠,thinkingJAVA和学习笔记

    这本书以其深入浅出的讲解方式,详尽地介绍了Java语言的各个方面。它不仅包含基本语法,还涉及设计模式、泛型、并发编程等高级话题,是进阶Java开发者的必读之作。中文版的提供使得中文读者能够无障碍地学习这本权威...

    vc源代码合集0951.rar

    2012-06-12 11:55 3,721,136 VC++动态链接库(dll)编程深入浅出.rar 2012-06-12 13:02 23,185 VC++图像平滑处理+程序.rar 2012-06-12 12:12 45,056 VC++操作INI配置文件的实现.doc 2012-06-12 11:48 11,728,284 VC++...

    《Effective C++(中文版)》

    通过以上概述,我们可以看到《Effective C++(中文版)》不仅是一本技术手册,更是一部深入浅出地介绍C++编程精髓的作品。无论是初学者还是有一定经验的开发者,都能从中受益匪浅。阅读这本书不仅可以帮助我们提高...

    Programming in Go-带书签目录超清文字版.pdf

    这本书深入浅出地介绍了Go语言的设计理念、语法特性和实际应用,旨在帮助读者快速掌握Go语言并能进行高效的编程实践。 Go语言,由Google公司的Robert Griesemer、Rob Pike及Ken Thompson等人设计开发,于2009年公开...

    Head First Servlet JSP(中文版)

    这本书以易理解的图文并茂的形式,深入浅出地讲解了这两个重要技术。 Servlet是Java编程语言中的一个接口,用于扩展服务器的功能,特别是Web服务器。它允许程序员创建动态、交互式的HTTP服务。Servlet可以处理...

    javaee经典学习资料大全

    - JavaEE进阶之Spring事务深入浅出:虽然Spring是Java EE的一个补充框架,但它的事务管理部分在企业级应用中非常重要,值得深入学习。 - J2EEWeb应用开发技术教材:Web层的开发是Java EE应用中的关键部分,学习如何...

    原版think in java4

    这本书以其深入浅出的讲解方式和全面的内容覆盖,成为了学习Java语言的重要参考书籍。中文版的出现使得更多的中国读者能够无障碍地理解和掌握Java编程精髓。 在描述中提到,“非扫描”意味着这是一份正式授权的电子...

    Java并发编程实战(中文版).rar

    总的来说,《Java并发编程实战》中文版是一本深入浅出的并发编程指南,无论你是初学者还是经验丰富的开发者,都能从中获得宝贵的知识和启示。通过学习书中的内容,你将具备驾驭Java并发编程的能力,写出更健壮、高效...

    android开发资料大全

    《深入浅出Android--Google手持设备应用程序设计》下载 《Android编程指南》android-book.pdf 下载 《Android应用开发揭秘》PDF高清版下载 游戏项目分享——忍者突袭 只发精品——分享一个短信应用源码 百度地图...

    重构_改善既有代码的设计.rar

    8. **侯捷译本**:侯捷是中国知名的软件技术专家,他的翻译风格深入浅出,使得原书的概念和方法论更加贴近中文读者的理解。 9. **超星版**:超星版通常指的是电子版,可能包含了一些电子阅读特有的标记或格式,方便...

    51CTO下载-【android资料免豆下载】汇总大量教程+工具+源码下载地址.pdf

    4. Android 深入浅出:包括 Android 的设计模式、架构设计、性能优化、安全机制等高级技术。 5. Android 开发入门与实践:涵盖 Android 开发的基础知识和实践操作,包括 Android Studio 的使用、 Android 项目结构...

    完整版大话练法.rar

    “大话”在中文里通常用来形容深入浅出地讲述复杂话题,这里的“大话练法”可能是作者以轻松幽默的方式讨论编程技巧和职业发展路径的一种方式。在IT行业,不断学习和提升技能是每个从业者必须面对的挑战,而这本书很...

    Cisco路由手册中文

    这份手册深入浅出地讲解了Cisco路由器的工作原理、配置步骤以及常见问题的解决方法,是了解和掌握网络基础特别是Cisco技术的宝贵资料。 在【描述】中提到,"Cisco路由手册中文非常适合新手学习",这意味着手册以...

Global site tag (gtag.js) - Google Analytics