`
eka72eka
  • 浏览: 14084 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

设计模式分解java(2)

阅读更多

设计模式分解java(2)
2010年12月20日
  当然也可以结合工厂模式来创建AbstractSpoon实例。  在Java中Prototype模式变成clone()方法的使用,由于Java的纯洁的面向对象特性,
    使得在Java中使用设计模式变得很自然,两者已经几乎是浑然一体了。这反映在很多模式上,如Interator遍历模式。
    /**------------------------------------------------------------------------------*/
    创建模式.Builder
    Builder模式定义:
    将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.
    Builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们.
    用户不知道内部的具体构建细节.Builder模式是非常类似抽象工厂模式,
    细微的区别大概只有在反复使用中才能体会到.
    为何使用?
    是为了将构建复杂对象的过程和它的部件解耦.注意: 是解耦过程和部件.
    因为一个复杂的对象,不但有很多大量组成部分,如汽车,有很多部件:车轮 方向盘 发动机还有各种小零件等等,
    部件很多,但远不止这些,如何将这些部件装配成一辆汽车,这个装配过程也很复杂(需要很好的组装技术),
    Builder模式就是为了将部件和组装过程分开.
    如何使用?
    首先假设一个复杂对象是由多个部件组成的,Builder模式是把复杂对象的创建和部件的创建分别开来,
    分别用Builder类和Director类来表示.
    首先,需要一个接口,它定义如何创建复杂对象的各个部件:
    public interface Builder {
    //创建部件A  比如创建汽车车轮
    void buildPartA();
    //创建部件B 比如创建汽车方向盘
    void buildPartB();
    //创建部件C 比如创建汽车发动机
    void buildPartC();
    //返回最后组装成品结果 (返回最后装配好的汽车)
    //成品的组装过程不在这里进行,而是转移到下面的Director类中进行.
    //从而实现了解耦过程和部件
    Product getResult();
    }
    用Director构建最后的复杂对象,而在上面Builder接口中封装的是如何创建一个个部件
    (复杂对象是由这些部件组成的),也就是说Director的内容是如何将部件最后组装成成品:
    public class Director {
    private Builder builder;
    public Director( Builder builder ) {
    this.builder = builder;
    }
    // 将部件partA partB partC最后组成复杂对象
    //这里是将车轮 方向盘和发动机组装成汽车的过程
    public void construct() {
    builder.buildPartA();
    builder.buildPartB();
    builder.buildPartC();
    }
    }
    Builder的具体实现ConcreteBuilder:
    通过具体完成接口Builder来构建或装配产品的部件;
    定义并明确它所要创建的是什么具体东西;
    提供一个可以重新获取产品的接口:
    public class ConcreteBuilder implements Builder {
    Part partA, partB, partC;
    public void buildPartA() {
    //这里是具体如何构建partA的代码
    };
    public void buildPartB() {
    //这里是具体如何构建partB的代码
    };
    public void buildPartC() {
    //这里是具体如何构建partB的代码
    };
    public Product getResult() {
    //返回最后组装成品结果
    };
    }
  复杂对象:产品Product:
    public interface Product { }
    复杂对象的部件:
    public interface Part { }
    我们看看如何调用Builder模式:
    ConcreteBuilder builder = new ConcreteBuilder();
    Director director = new Director( builder );
    director.construct();
    Product product = builder.getResult();
    Builder模式的应用
    在Java实际使用中,我们经常用到"池"(Pool)的概念,当资源提供者无法提供足够的资源,
    并且这些资源需要被很多用户反复共享时,就需要使用池.
    "池"实际是一段内存,当池中有一些复杂的资源的"断肢"(比如数据库的连接池,也许有时一个连接会中断),
    如果循环再利用这些"断肢",将提高内存使用效率,提高池的性能.
    修改Builder模式中Director类使之能诊断"断肢"断在哪个部件上,再修复这个部件.
    /**------------------------------------------------------------------------------*/
    创建模式.Singleton
    定义:
    Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。
    在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。
    还有, singleton能够被状态化; 这样,多个单态类在一起就可以作为一个状态仓库一样向外提供服务,比如,你要论坛中的帖子计数器,每次浏览一次需要计数,单态类能否保持住这个计数,并且能synchronize的安全自动加1,如果你要把这个数字永久保存到数据库,你可以在不修改单态接口的情况下方便的做到。
    另外方面,Singleton也能够被无状态化。提供工具性质的功能,
    Singleton模式就为我们提供了这样实现的可能。使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage collection)。
    我们常常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,因为被装入的类实际也属于资源。
    如何使用?
    一般Singleton模式通常有几种形式:
    public class Singleton {
    private Singleton(){}
    //在自己内部定义自己一个实例,是不是很奇怪?
    //注意这是private 只供内部调用
    private static Singleton instance = new Singleton();
    //这里提供了一个供外部访问本class的静态方法,可以直接访问
    public static Singleton getInstance() {
    return instance;
    }
    }
    第二种形式:
    public class Singleton {
    private static Singleton instance = null;
    public static synchronized Singleton getInstance() {
    //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次
    //使用时生成实例,提高了效率!
    if (instance==null)
    instance=new Singleton();
    return instance;   }
    }
    使用Singleton.getInstance()可以访问单态类。
    上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。
    注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用 getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴趣者进一步研究。
    一般认为第一种形式要更加安全些。
    使用Singleton注意事项:
    有时在某些情况下,使用Singleton并不能达到Singleton的目的,如有多个Singleton对象同时被不同的类装入器装载;在EJB这样的分布式系统中使用也要注意这种情况,因为EJB是跨服务器,跨JVM的。
    我们以SUN公司的宠物店源码(Pet Store 1.3.1)的ServiceLocator为例稍微分析一下:
    在Pet Store中ServiceLocator有两种,一个是EJB目录下;一个是WEB目录下,我们检查这两个ServiceLocator会发现内容差不多,都是提供EJB的查询定位服务,可是为什么要分开呢?仔细研究对这两种ServiceLocator才发现区别:在WEB中的 ServiceLocator的采取Singleton模式,ServiceLocator属于资源定位,理所当然应该使用Singleton模式。但是在EJB中,Singleton模式已经失去作用,所以ServiceLocator才分成两种,一种面向WEB服务的,一种是面向EJB服务的。
  Singleton模式看起来简单,使用方法也很方便,但是真正用好,是非常不容易,需要对Java的类 线程 内存等概念有相当的了解。
    /**------------------------------------------------------------------------------*/
    结构模式.Facade
    Facade的定义: 为子系统中的一组接口提供一个一致的界面.
    Facade一个典型应用就是数据库JDBC的应用,如下例对数据库的操作:
    public class DBCompare {
    Connection conn = null;
    PreparedStatement prep = null;
    ResultSet rset = null;
    try {
    Class.forName( "" ).newInstance();
    conn = DriverManager.getConnection( "" );
    String sql = "SELECT * FROM  WHERE  = ?";
    prep = conn.prepareStatement( sql );
    prep.setString( 1, "" );
    rset = prep.executeQuery();
    if( rset.next() ) {
    System.out.println( rset.getString( "也非常方便,比如从Mysql数据库换到Oracle数据库,只要更换 facade接口中的driver就可以.
    我们做成了一个Facade接口,使用该接口,上例中的程序就可以更改如下:
    public class DBCompare {
    String sql = "SELECT * FROM  WHERE  = ?";
    try {
    Mysql msql=new mysql(sql);
    prep.setString( 1, "" );
    rset = prep.executeQuery();
    if( rset.next() ) {
    System.out.println( rset.getString( "不能直接操作到某个对象,但又必须和那个对象有所互动.
    举例两个具体情况:
    (1)如果那个对象是一个是很大的图片,需要花费很长时间才能显示出来,
    那么当这个图片包含在文档中时,使用编辑器或浏览器打开这个文档,打开文档必须很迅速,
    不能等待大图片处理完成,这时需要做个图片Proxy来代替真正的图片.
    (2)如果那个对象在Internet的某个远端服务器上,
    直接操作这个对象因为网络速度原因可能比较慢,那我们可以先用Proxy来代替那个对象.
    总之原则是,对于开销很大的对象,只有在使用它时才创建,这个原则可以为我们节省很多宝贵的Java内存.
    所以,有些人认为Java耗费资源内存,我以为这和程序编制思路也有一定的关系.
  如何使用Proxy?
    以Jive论坛系统为例,访问论坛系统的用户有多种类型:注册普通用户 论坛管理者 系统管理者 游客,
    注册普通用户才能发言;论坛管理者可以管理他被授权的论坛;系统管理者可以管理所有事务等,
    这些权限划分和管理是使用Proxy完成的.
    Forum是Jive的核心接口,在Forum中陈列了有关论坛操作的主要行为,如论坛名称
    论坛描述的获取和修改,帖子发表删除编辑等.
    在ForumPermissions中定义了各种级别权限的用户:
    public class ForumPermissions implements Cacheable {
    /** Permission to read object.*/
    public static final int READ = 0;
    /** Permission to administer the entire sytem.*/
    public static final int SYSTEM_ADMIN = 1;
    /** Permission to administer a particular forum.*/
    public static final int FORUM_ADMIN = 2;
    /** Permission to administer a particular user.*/
    public static final int USER_ADMIN = 3;
    /** Permission to administer a particular group.*/
    public static final int GROUP_ADMIN = 4;
    /** Permission to moderate threads.*/
    public static final int MODERATE_THREADS = 5;
    /** Permission to create a new thread.*/
    public static final int CREATE_THREAD = 6;
    /** Permission to create a new message.*/
    public static final int CREATE_MESSAGE = 7;
    /** Permission to moderate messages.*/
    public static final int MODERATE_MESSAGES = 8;
    .....
    public boolean isSystemOrForumAdmin() {
    return (values[FORUM_ADMIN] || values[SYSTEM_ADMIN]);
    }
    .....
    }
    因此,Forum中各种操作权限是和ForumPermissions定义的用户级别有关系的,
    作为接口Forum的实现:ForumProxy正是将这种对应关系联系起来.
    比如,修改Forum的名称,只有论坛管理者或系统管理者可以修改,代码如下:
    public class ForumProxy implements Forum {
    private ForumPermissions permissions;
    private Forum forum;
    this.authorization = authorization;
    public ForumProxy(Forum forum, Authorization authorization,
    ForumPermissions permissions)
    {
    this.forum = forum;
    this.authorization = authorization;
    this.permissions = permissions;
    }
    .....
    public void setName(String name) throws UnauthorizedException,
    ForumAlreadyExistsException
    {
    //只有是系统或论坛管理者才可以修改名称
    if (permissions.isSystemOrForumAdmin()) {
    forum.setName(name);
    }
    else {
    throw new UnauthorizedException();
    }
    }
    ...
    }
    而DbForum才是接口Forum的真正实现,以修改论坛名称为例:
    public class DbForum implements Forum, Cacheable {
    ...
    public void setName(String name) throws ForumAlreadyExistsException {
    ....
    this.name = name;
    //这里真正将新名称保存到数据库中
    saveToDb();
    ....
    }
    ...
    }
    凡是涉及到对论坛名称修改这一事件,其他程序都首先得和ForumProxy打交道,
    由ForumProxy决定是否有权限做某一样事情,ForumProxy是个名副其实的"网关","安全代理系统".
    在平时应用中,无可避免总要涉及到系统的授权或安全体系,不管你有无意识的使用Proxy,实际你已经在使用Proxy了.
分享到:
评论

相关推荐

    Java多功能计算器+设计模式+开发文档

    一共使用了建造者模式、状态模式、命令模式、策略模式、单件模式这5个设计模式。 本次课程设计是开发一款有多个面板的计算器。不仅有针对日常生活“标准型”面板、针对理工科计算的“科学型”面板、针对于编程人员...

    研磨设计模式带书签 分解一

    研磨设计模式带书签完整版,研磨设计模式带书签 ,研磨设计模式带书签

    现代Java EE设计模式:构建可扩展架构Modern Java EE Design Patterns: Building Scalable Architecture

    本书将帮助您了解启动绿地​​开发与将现有的棕地应用程序分解为服务所面临的挑战,并检查您的业务领域,以了解微服务是否合适。

    java餐饮管理系统源码加数据库-designmodel:设计模式

    java餐饮管理系统源码加数据库 designmodel 设计模式 六大原则 1.单一职责原则:只做一...开发人员A碰到了一个问题,就找开发B,开发B说用"xxxx设计模式就行了",如果这个时候开发A不懂设计模式,那他们就无法交流了。就

    JAVA设计模式逐个解析!

    详解各个模式 建造者模式,装饰模式,状态模式,工厂模式

    多线程设计模式——Pipeline(流水线)模式

    可以将任务的处理分解为若干个处理阶段,上一个阶段任务的结果交给下一个阶段来处理,这样每个线程的处理是并行的,可以充分利用资源提高计算效率。 模式所使用的类:Pipe对处理阶段的抽象,负责对输入进行处理,并...

    2023java最新面试资料汇总

    面试题包括以下十九部分:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql...

    java简易版开心农场源码-Design-Patterns:「设计模式」

    23种设计模式 设计模式七大原则 1)单一职责原则 2)接口隔离原则 3)依赖倒转(倒置)原则 4)里氏替换原则 5)开闭原则 6)迪米特法则 7)合成复用原则 单一职责原则 ​ 对类来说的,即一个类应该只负责一项职责...

    java版五子棋源码-DesignPattern:设计模式

    设计模式 设计原则 1.单一职责原则 对类来说,一个类应该只负责一项职责。如果一个类负责多项职责,可分解多个类来完成。 2.接口隔离原则 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小...

    AIC的Java课程1-6章

    第12章 IO与串行化 2课时  了解Java IO 中类的层次结构,介绍Java IO采用的装饰器模式。  学会使用File,FileReader,BufferedReader,FileWriter,BufferedWriter,PrintWriter等类输入...

    Java语言的科学与艺术 斯坦福大学经典教材

     第1章 前言 1.1 计算简史 1.2 计算机科学的含义 1.3 计算机硬件简介 1.4 算法 1.5 编程过程的几个阶段 1.6 Java和面向对象范例 1.7 Java和WWW   1.8 小结 1.9 复习题 第2章 编程示例 2.1 “Hello world”程序 ...

    java范例开发大全源代码

     8.3 面向对象的设计模式 241  实例156 Singleton单例模式 242  实例157 招聘(简单工厂模式) 243  实例158 同学聚会(工厂方法模式) 244  实例159 图书展(抽象工厂模式) 246  实例160 汽车...

    java范例开发大全

    8.3 面向对象的设计模式 241 实例156 Singleton单例模式 242 实例157 招聘(简单工厂模式) 243 实例158 同学聚会(工厂方法模式) 244 实例159 图书展(抽象工厂模式) 246 实例160 汽车适配器(Adapter适配器模式...

    Java范例开发大全 (源程序)

     8.3 面向对象的设计模式 241  实例156 Singleton单例模式 242  实例157 招聘(简单工厂模式) 243  实例158 同学聚会(工厂方法模式) 244  实例159 图书展(抽象工厂模式) 246  实例160 汽车适配器...

    java简易版开心农场源码-Design-Patterns:23种设计模式

    23种设计模式 设计模式七大原则 1)单一职责原则 2)接口隔离原则 3)依赖倒转(倒置)原则 4)里氏替换原则 5)开闭原则 6)迪米特法则 7)合成复用原则 单一职责原则 ​ 对类来说的,即一个类应该只负责一项职责...

    Java语言的科学与艺术(国外计算机科学经典教材)

    第2章 编程示例  2.1 “Hello world”程序  2.2 编程过程的观点  2.3 两数相加的程序  2.4 编程习语和模式  2.5 类和对象  2.6 图形程序  2.7 小结  2.8 复习题  2.9 编程练习 第3章 表达式  3.1 原始数据...

    Java范例开发大全(全书源程序)

    8.3 面向对象的设计模式 241 实例156 Singleton单例模式 242 实例157 招聘(简单工厂模式) 243 实例158 同学聚会(工厂方法模式) 244 实例159 图书展(抽象工厂模式) 246 实例160 汽车适配器(Adapter...

    Java课程设计-教务系统管理.doc

    所谓规范化是用来改造关系模式,通过 分解关系模式来消除其中不合适的数据依赖,以解决插入异常、删除异常、更新异常和 数据冗余问题。完整性约束包括实体完整性、参照完整性和用户自定义完整性。 1. 基本表设计 1) ...

    Java核心技术II(第8版)

    第一章 流与文件 1.1 流 1.1.1 读入和写出字节 1.1.2 完整的流家族 1.1.3 组合流过滤器 1.2 文本输入与输出 1.2.1 如何写出文本输出 ...12.10.2 访问注册表的Java平台接口 12.10.3 以本地方法方式实现注册表访问函数

    基于Java的软件项目管理系统的设计与实现【附源码】

    本设计主要实现集人性化、高效率、便捷等优点于一身的软件项目管理系统,完成版本管理、沟通管理、项目经理管理、员工管理、软件任务管理、任务分解管理、任务分配管理、进度汇报管理、开发成本估算管理、数据可视化...

Global site tag (gtag.js) - Google Analytics