博客详情

java设计模式(二) (原创)

作者: 朝如青丝暮成雪
发布时间:2017-09-23 08:36:56  文章分类:java编程   阅读(833)  评论(0)
设计模式中的第一类是创建型模式, 共5种:
  工厂方法、 抽象工厂、单例、原型、构建者(生成器)

  1、工厂方法模式,含简单工厂、工厂方法、静态工厂,通常而言我们所说的工厂模式,如无特别说明,均指工厂方法模式。

其中简单工厂模式是工厂方法模式的一种最简单存在形式。
简单工厂模式:
  首先是有3个产品其中一个是抽象产品,另2个产品实现抽象产品。    

package com.jelly.mypattern.simpleFactory;  
  
/** 
 * 抽象发送器  
 *     如 可以表示邮件、短信 等发送器  
 * @author jelly 
 * 
 */  
public interface ISender {  
     
    public void send(String content);//发送的方法  
}  

package com.jelly.mypattern.simpleFactory;  
  
/** 
 * 邮件发送器  产品 
 * @author jelly 
 * 
 */  
public class MailSender implements ISender{  
  
    @Override  
    public void send(String content) {  
        //邮件发送器 , 发送一封邮件  
        System.out.println("send a mail:"+content);  
    }  
}  


package com.jelly.mypattern.simpleFactory;  
  
/** 
 * 短信发送器    产品 
 * @author jelly 
 * 
 */  
public class SmsSender  implements ISender{  
  
    @Override  
    public void send(String content) {  
      //短信发送器 发送 方法:发送一条短信  
        System.out.println("send a sms:"+content);  
    }  
} 
 

工厂类,生产发送器产品

package com.jelly.mypattern.simpleFactory;  
/** 
 * 简单 工厂  
 * 生产发送器 
 * @author jelly 
 * 
 */  
public class SenderFactory {  
    public  ISender  getSender(String senderType){  
        ISender sender=null;  
        if(senderType.equals("sms")){  
            sender=new SmsSender();  
        }  
        else if(senderType.equals("mail")){  
            sender=new MailSender();  
        }  
        return sender;  
    }  
}  

测试程序代码

package com.jelly.mypattern.simpleFactory;  
  
/** 
 * 客户端 测试类 
 * @author jelly 
 * 
 */  
public class SimpleFactoryTest {  
      
     /** 
      * Simple Factory  
      * 简单工厂模式总结: 
      *    1、 工厂只有一个,且工厂中创建产品的方法也只有一个。 
      *    2、客户端代码中要得到产品,只能调用通过工厂中的这个方法,传入不同的产品类型,得到具体的某个产品。 
      *    3、每新增一种新的产品都需要在工厂方法中新增一种产品类型。 
      */  
    public static void main(String[] args) {  
        SenderFactory   senderFactory=new SenderFactory();  
        ISender sender=     senderFactory.getSender("sms");  
        sender.send("你好 world");  
        ISender sender2=    senderFactory.getSender("mail");  
        sender2.send("你好 world");  
    }  
}  


工厂方法模式:
与简单工厂不同,工厂方法模式中每新增生产一个产品,就需要新加一个工厂方法,而简单工厂中需要新加一个产品类型的参数值即可。
改写工厂类

/** 
 * 工厂  
 * 生产发送器 
 * @author jelly 
 * 
 */  
public class SenderFactory {  
     public  ISender getSmsSender(){  
         return new SmsSender();  
     }  
     public  ISender getMailSender(){  
         return new MailSender();  
     }  
}  

测试程序代码

package com.jelly.mypattern.factoryMethod;  
  
/** 
 * 客户端 调用测试 类 
 * @author jelly 
 * 
 */  
public class FactoryMethodTest {  
    
    /** 
     * Factory Method   
     * 工厂 方法模式总结: 
     *  1  此模式中工厂有一个,工厂中的方法有多个。  
     *  2 每新增一种产品就需要在工厂中新加一个生产方法 
     */  
    public static void main(String[] args) {  
      SenderFactory   senderFactory=new SenderFactory();  
      ISender sender= senderFactory.getMailSender();  
      sender.send("你好 world");  
      ISender sender2= senderFactory.getSmsSender();  
      sender2.send("你好 world");  
   }  
}  


静态工厂模式(属于工厂模式的静态变体),与工厂模式使用基本相同,静态工厂模式不用创建工厂对象。
还是改写工厂类,把类中的实例方法改为静态方法即可。

package com.jelly.mypattern.staticFactory;  

/** 
 * 发送器   静态工厂 
 * @author jelly 
 * 
 */  
public class SenderFactory {  
      
    /** 
     * 生产 smsSender 
     * @return 
     */  
     public static   ISender getSmsSender(){  
         return new SmsSender();  
     }  
     /** 
      * 生产 MailSender 
      * @return 
      */  
     public static   ISender getMailSender(){  
         return new MailSender();  
     }  
}  

测试代码

package com.jelly.mypattern.staticFactory;  
  
/** 
 * 静态工厂 客户端测试类  
 * @author jelly 
 * 
 */  
public class StaticFactoryTest {  
    /** 
     * 静态工厂模式: 
     *  也称为静态工厂方法模式,属于工厂方法模式的静态变体。 
     *  与工厂方法模式的使用相同,只是无须创建工厂对象。 
     * 
     */  
    public static void main(String[] args) {  
       ISender sender=  SenderFactory.getMailSender();  
      sender.send("你好 world");  
        
      ISender sender2=  SenderFactory.getSmsSender();  
      sender2.send("你好 world");  
    }  
}  



2 抽象工厂模式:
与工厂方法模式不同,抽象工厂模式中不仅仅产品是抽象的,工厂也是抽象的。 不同的工厂才会生成具体的产品。
改写工厂类的层次结构,最上层有一个抽象工厂,下面有2个具体的子工厂去实现它。

package com.jelly.mypattern.abstractFactory;  
  
/** 
 * 抽象工厂 
 * @author jelly 
 * 
 */  
public interface ISenderFactory {  
      
    /** 
     * 生产发送器  
     * @return 
     */  
    public  ISender getSender();  
      
}  

package com.jelly.mypattern.abstractFactory;  
  
public class MailSenderFactory  implements ISenderFactory {  
  
    /** 
     * 生产邮件发送器 
     */  
    @Override  
    public ISender getSender() {  
         return new   MailSender();  
    }  
  
}  


package com.jelly.mypattern.abstractFactory;  
  
/** 
 * 短信发送器  工厂 
 * @author jelly 
 * 
 */  
public class SmsSenderFactory implements ISenderFactory{  
    /** 
     * 生产短信发送器 
     */  
    @Override  
    public ISender getSender() {  
        return new SmsSender();  
    }  
}  

测试代码

package com.jelly.mypattern.abstractFactory;  
  
/** 
 * 抽象工厂模式  客户端调用测试类 
 * @author jelly 
 * 
 */  
public class AbstractFactoryTest {  
      
    /** 
     * 抽象工厂模式总结: 
     *  1 在工厂类层次接口中的顶层有一个抽象的工厂,生产抽象的产品 
     *  2 抽象工厂派生出具体的工厂类,在具体的工厂类中生产具体的产品 
     *  3 如需要新增一种生产产品,则需要新增一个工厂类 
     */  
    public static void main(String[] args) {  
        //得到工厂  
        ISenderFactory senderFactory=new SmsSenderFactory();  
        //工厂生产产品  
        ISender sender =senderFactory.getSender();  
        //使用产品  
        sender.send("你好 world");  
        ISenderFactory senderFactory2=new  MailSenderFactory();  
        ISender sender2 =senderFactory2.getSender();  
        sender2.send("你好 world");  
    }  
}  




3 单例模式 ,在整个应用中此类只有一个实例对象。
   单例模式中的懒人模式比较复杂,涉及多线程并发的问题,这里不做讨论,有兴趣的可以自行研究。
   一般而言,单例模式可以采用以下方式直接创建,当类加载到jvm中时即创建了一个此类的实例对象。

package com.jelly.mypattern.singleton;  
  
/** 
 * 单例模式   
 * @author jelly 
 * 
 */  
public class SingleClass {  
    private static   SingleClass instance=new SingleClass();  
    /** 
     * 私有化构造方法 
     */  
    private  SingleClass(){  
    }  
    /** 
     * 暴露公有的静态方法  得到一个实例对象 
     * @return 
     */  
    public static  SingleClass  getInstance(){  
        return instance;  
    }  
    //实例方法  
    public  void  aMethod(){  
        System.out.println("execute aMethod 方法");  
    }  
    //实例方法  
    public void bMethod(){  
        System.out.println("execute bMethod 方法");  
    }  
}  


package com.jelly.mypattern.singleton;  
  
/** 
 * 单例模式 客户端调用测试类 
 * @author jelly 
 * 
 */  
public class SingleClassTest {  
   /**单例模式: 
    *1 保证在整个应用程序中此类只有一个实例对象。 
    *2 采用单实例对象承担此类的所有职责。 
    * @param args 
    */  
     public static void main(String[] args) {  
        SingleClass single=SingleClass.getInstance();  
        single.aMethod();//调用实例对象的a方法  
        single.bMethod();//调用实例对象的b方法  
     }  
}  



4、原型模式   Prototype
     原型模式:
    1 以一个对象为原型,复制克隆出一个新对象。
    2 当创建新对象的代价很高、很费时,可以通过原型对象克隆新对象。
    3  克隆对象必须实现序列化接口(标记接口)
    4  克隆对象必须使用到深克隆。


package com.jelly.mypattern.prototype;  
  
import java.io.ByteArrayInputStream;  
import java.io.ByteArrayOutputStream;  
import java.io.IOException;  
import java.io.ObjectInputStream;  
import java.io.ObjectOutputStream;  
import java.io.Serializable;  
   
/** 
 * 业务类 
 * @author jelly 
 * 
 */  
public class MyClass implements Serializable{  
       
    private static final long serialVersionUID = 6468810466201374898L;  
    private String name;  
   
    public MyClass() {  
        super();  
    }  
    public MyClass(String name) {  
        super();  
        this.name = name;  
    }  
    public  void aMethod(){  
        System.out.println("执行 aMethod 方法: "+name);  
    }  
    public void bMethod(){  
        System.out.println("执行 bMethod 方法: "+name);  
    }  
     /** 
      * 深克隆 
      * @return 
      * @throws IOException 
      * @throws ClassNotFoundException 
      */  
    public MyClass deepClone() throws IOException, ClassNotFoundException {    
        ByteArrayOutputStream bos = new ByteArrayOutputStream();    
        ObjectOutputStream oos = new ObjectOutputStream(bos);    
        oos.writeObject(this);    
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());    
        ObjectInputStream ois = new ObjectInputStream(bis);    
        return (MyClass) ois.readObject();    
    }  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
}  
package com.jelly.mypattern.prototype;  
  
import java.io.ByteArrayInputStream;  
import java.io.ByteArrayOutputStream;  
import java.io.IOException;  
import java.io.ObjectInputStream;  
import java.io.ObjectOutputStream;  
import java.io.Serializable;  
  
/** 
 * 克隆工具类 
 * @author jelly 
 * 
 */  
public class CloneUtil {  
     
    /** 
     * 对实现Serializable 接口的对象进行 完全的克隆 
     * @param obj 
     * @return 
     * @throws IOException 
     * @throws ClassNotFoundException 
     */  
    public  static Serializable deepClone(Serializable  obj)throws IOException, ClassNotFoundException{  
         
        ByteArrayOutputStream bos = new ByteArrayOutputStream();    
        ObjectOutputStream oos = new ObjectOutputStream(bos);    
        oos.writeObject(obj);    
        
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());    
        ObjectInputStream ois = new ObjectInputStream(bis);    
        return (Serializable) ois.readObject();   
    }  
}  

测试代码

package com.jelly.mypattern.prototype;  
 
/** 
 * 原型模式 客户端测试类 
 * @author jelly 
 * 
 */  
public class PrototypeTest {  
    /** 
     * Prototype 模式 
     * 原型模式   
     * 1  通过某个对象为原型(模型),克隆出一个新对象的方式创建新对象。 
     * 2  克隆对象必须实现序列化接口(标记接口) 
     * 3  克隆对象必须使用到深克隆。 
     * @param args 
     * @throws Exception 
     */  
     public static void main(String[] args)  throws Exception{  
        MyClass obj1=new MyClass("张三");  
        MyClass obj2= obj1.deepClone();  
                obj2.setName("李四");  
         obj2.aMethod();   
         obj2.bMethod();   
           
         obj1.aMethod();   
         obj1.bMethod();   
         MyClass   obj3=(MyClass) CloneUtil.deepClone(obj2);  
          obj3.setName("王五");  
          obj3.aMethod();  
          obj3.bMethod();  
           
     }  
}  


5 构造者(生成器) 模式
   Builder
  构建者模式 ,也称作生成器模式
  1  将类对象的构建过程单独抽取出来封装,使对象的业务逻辑和对象的构建逻辑分离开。
  2  当构建对象的逻辑较复杂,且容易发生变动时最好使用构建者模式。
  3  通常用于读取配置文件、xml文件构建一个对象。

package com.jelly.mypattern.builder;  
  
/** 
 *  
 * 邀请函(某活动)   
 * @author jelly 
 * 
 */  
public class Invitation {  
      
    private  String subject;//邀请的主题    
    private   String holder;//活动举办者  举办方   举办机构  
    private  String  holderTime;//举办时间  
    private  String  holderPlace ;//举办地点  
    private   String invitName;//被邀请人姓名  
    public String getSubject() {  
        return subject;  
    }  
    public void setSubject(String subject) {  
        this.subject = subject;  
    }  
    public String getHolder() {  
        return holder;  
    }  
    public void setHolder(String holder) {  
        this.holder = holder;  
    }  
    public String getHolderTime() {  
        return holderTime;  
    }  
    public void setHolderTime(String holderTime) {  
        this.holderTime = holderTime;  
    }  
    public String getHolderPlace() {  
        return holderPlace;  
    }  
    public void setHolderPlace(String holderPlace) {  
        this.holderPlace = holderPlace;  
    }  
    public String getInvitName() {  
        return invitName;  
    }  
    public void setInvitName(String invitName) {  
        this.invitName = invitName;  
    }  
    @Override  
    public String toString() {  
        return "Invitation [subject=" + subject + ", holder=" + holder  
                + ", holderTime=" + holderTime + ", holderPlace=" + holderPlace  
                + ", invitName=" + invitName + "]";  
    }  
       
}  

package com.jelly.mypattern.builder;  
  
import java.io.BufferedReader;  
import java.io.FileReader;  
  
/** 
 * 邀请函的构建者 (生成器) 类 
 * @author jelly 
 * 
 */  
public class InvitationBuilder {  
       
    /** 
     * 根据配置文件,构造出一个邀请函对象 
     * @param path 
     * @return 
     * @throws Exception 
     */  
    public Invitation  build(String path) throws Exception{  
           Invitation invitation=null;    
           BufferedReader reader=null;  
       try {  
           reader=new BufferedReader(new FileReader(path));  
           String line= reader.readLine();  
           String[] ss=  line.split(",");  
           invitation=new Invitation();  
           invitation.setSubject(ss[0]);  
           invitation.setHolder(ss[1]);  
           invitation.setHolderTime(ss[2]);  
           invitation.setHolderPlace(ss[3]);  
           invitation.setInvitName(ss[4]);  
           return invitation;  
        } finally {  
             reader.close();  
        }  
    }  
}  

invitation.txt

第十七届武汉国际汽车展览会,武汉市人民政府和中国国际贸易促进委员会,2016年10月12-17日,武汉国际博览中心,张晓明  
  
#邀请函内容由活动主题 、举办机构/单位、  活动时间、活动地点和被邀请人姓名5个部分组成,各部分间以逗号隔开。  


测试代码 
package com.jelly.mypattern.builder;  
  
/** 
 * 构建者模式  测试类 
 * @author jelly 
 * 
 */  
public class BuilderTest {  
    /** 
     * Builder  
     * 构建者模式: 
     *  1  将类对象的构建过程单独抽取出来封装,使对象的业务逻辑和对象的构建逻辑分离开。 
     *  2  当构建对象的逻辑较复杂,且容易发生变动时最好使用构建者模式。 
     *  3  通用用于读取配置文件、xml文件构建一个对象。 
     *   
     */  
    public static void main(String[] args) throws Exception {  
        InvitationBuilder builder=new InvitationBuilder();  
        String path=BuilderTest.class.getResource("invitation.txt").getPath();  
        Invitation invitation= builder.build(path);//构建出Invitation类的一个实例  
        System.out.println(invitation);  
    }  
}  


关键字:  设计模式  java
评论信息
暂无评论
发表评论

亲,您还没有登陆,暂不能评论哦! 去 登陆 | 注册

博主信息
   
数据加载中,请稍候...
文章分类
   
数据加载中,请稍候...
阅读排行
 
数据加载中,请稍候...
评论排行
 
数据加载中,请稍候...

Copyright © 叮叮声的奶酪 版权所有
备案号:鄂ICP备17018671号-1

鄂公网安备 42011102000739号