# JavaDesignPattern **Repository Path**: gaopengfei/JavaDesignPattern ## Basic Information - **Project Name**: JavaDesignPattern - **Description**: Java的23种设计模式。 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2015-04-21 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #JavaDesignPattern# #UML类图# ![](http://i.imgur.com/ZUEYH1N.jpg) # 单态设计模式 # **org.gpf.singleton** JDK中的`java.lang.Runtime`类是单态模式的具体体现。它是锇汉实现 ## Singleton1 ## 单态模式的锇汉式实现,线程安全。 ## Singleton2 ## 单态模式的懒汉式实现,非线程安全。 ## Singleton3 ## 在取得实例的方法上加锁,实现懒汉模式的线程安全。但是效率不高。 ## Singleton4 ## 使用双重检查和同步代码块实现懒汉模式的线程安全,比起Singleton3效率大大提高。 ## Singleton5 ## 加入volatile关键字改进了双重锁机制 ## Singleton6 ## 使用静态内部类实现单态模式 ## Singleton7 ## 使用枚举实现单态模式。枚举很方便,同时又不会有线程安全的问题。 ## SingletonTest ## 单态模式的测试类。日常开发中常常使用单台模式的锇汉式。因为它比较简单,不会有多线程的问题。 *特别注意:* **单态模式并不是万能的,可以通过Java的反射机制取得私有化构造器,并将此构造器设置为可见,那么所有的单台模式将失效!** # 简单工厂模式 # **org.gpf.simpleFactory** 采用面向对象的语言写一个计算器。 ![](http://i.imgur.com/q56wLEl.jpg) 输入运算符号,工厂就可以实例化出合适的对象,通过多态返回父类的方式实现了计算器的结果。 - 如果后期我们需要更改加法运算的实现,只需要更改`OperationAdd`类即可 - 如果我们需要增加平方的运算只需要增加相应的子类`OperationSqrt`并且修改工厂类,在switch中增加一个分支。 - 如果需要更改界面层,则实现运算功能的代码根本不需要更改任何东西,因为它们之间一点关系都没有! # 策略模式 # 做一个商场收银软件,营业员根据客户所购买的的商品的单价和数量向客户收费。在入手软件的时候需要考虑到以后的各种变化:例如:商品可能会打折【一折、二折……】,上平还有可能满300减100等等各种情况。 ## 简单工厂实现 ## 面向对象编程并不是类越多越好——类的划分是为了封装,分类的基础是抽象。**具有相同属性和功能的对象的集合才是类**。打一折和打九折只是形式不同,抽象出来所有的打折算法都是一样的——打折算法应该是一个类。 ![](http://i.imgur.com/FDdwgyl.jpg) 简单工厂模式虽然实现了以上功能,但是如果商场增加了一种新的促销手段(例如满100送10积分,积分到达一定的程度可以兑换奖品)就需要反复修改工厂增加`switch-case`分支。**面对算法的经常变更应该有更好的模式。** ## 策略模式实现 ## 策略模式定义了算法家族,分别封装起来,让它们之间可以相互替换。——**此模式让算法的变化不会影响要使用算法的客户**。 # 模板方法模式Template Method # 准备一个抽象类,将部分逻辑以具体方法的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。 ## 模板方法模式的结构 ## - 抽象模板角色 - 定义了一个或者多个抽象操作,以便让子类实现 - 定义并实现了一个模板方法 - 具体模板角色 - 实现父类所定义的一个或者多个抽象方法 - 每一个抽象模板都可以有任意多个具体模板角色与之对应,每一个具体模板角色都可以给出这些抽象方法的不同实现。 ## 造电脑 ## `org.gpf.templateMethod.PCDemo` - 抽象模板角色:Template类 - 具体模板角色:NoteBook类和PC类 ## JSP中的模板方法模式 ## `HttpServlet`类提供了一个`service()`方法。这个方法调用了一个或者几个do方法,完成对客户端调用的处理,这些do方法则要由具体的`HttpServlet`类提供。那么这里的`service()`方法就是模板方法。 ## 测试程序的执行时间 ## `org.gpf.templateMethod.GetProgramStartEnd` 程序的开始时间和结束时间都是确定的(通过System.currentTimeMillis())。具体的运行的程序是不同的。对外提供一个`runcode()`方法,强制使子类去覆写。 对于模板方法模式:有一部分的功能是确定的,有一部分功能是不确定的。而确定的部分在使用不确定的部分,这时就将不确定的部分暴露出去由该类的子类去完成。 # 动态代理 # jdk1.3之后,java语言通过`java.lang.reflect`中的3个类直接吃吃代理模式,分别是`Proxy`、`InvocationHandler`和`Method`。 Proxy类使得当系统有了一个代理对象后,对源对象的方法调用会首先分配给一个调用处理器(InvocationHandler)接口,InvocationHandler接口中有一个`invoke()`方法。 ## 创建动态代理对象的步骤 ## 1. 指明一系列的接口来创建一个代理对象 2. 创建一个调用处理器(InvocationHandler)对象 3. 将这个代理指定为某个其他对象的代理对象 4. 在调用处理器的invoke方法中采取代理,一方面将调用传递给真实对象,另一方面执行各种需要的操作。 ## 电脑代理商 ## `org.gpf.dynamicProxy` - 抽象主题角色:SaleComputer - 真实主题角色:ComputerMaker - 代理主题角色:ComputerProxy - Java动态代理过程:ProxyFunction(自定义的一个类,由这个类来具体完成代理过程)