zoukankan      html  css  js  c++  java
  • 年末技术总结之设计模式 创建型模式

    1,马上农历年末了,在这一年中,到底学习了神马有用的技术知识,所谓温故知新,打算写下来,总结和提高一下,大致想这么写,看时间而定;

    2,首先就是设计模式的回顾,这个比较常用,大到设计系统,小到做需求,用到的频率都蛮高的,设计模式大致分成3类,创建型,结构型,行为型;创建型比较简单,这里先复习这个;

    3,先分开回顾,结合在工作当中碰到的问题,自己重新理解下,有神马不对的,各位屌丝兄弟指出来,共同进步;

    3.1 单例模式

      个人理解是为了保证数据的一致性使用这个模式;

    类别 详细
    简介 保证一个类只有一个实例,并提供一个访问实例的全局访问点,避免不一致的情况发生;
    参考 http://www.cnblogs.com/whgw/archive/2011/10/05/2199535.html
    实例分析
    package com.lifc.year.end.design.pattern.creation.singleton;
    
    public class Singleton {
        
        private static Singleton instance=new Singleton();
        
        private String name;
        
        
        
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        private Singleton()
        {
            
        }
    
        public static Singleton getInstance()
        {
            return instance;
        }
    }
    
    
    package com.lifc.year.end.design.pattern.creation.singleton;
    
    public class Client {
    
        /**
         * 创建时间: 2013-1-28 上午11:00:07
         * 创建人:cutter.li
         * 参数: 
         * 返回值: void
         * 方法描述 :
        */
        public static void main(String[] args) {
    
            Singleton s1=Singleton.getInstance();
            s1.setName("cutter.li");
            System.out.println(s1.getName());
            Singleton s2=Singleton.getInstance();
            System.out.println(s2.getName());
            
            System.out.println("单例吗?"+s1.equals(s2));
            
            
        }
    
    }
    说明
    单例的实现方式分成三类:1,饱汉式,我写的一个简单例子就是这种形式实现的;2,饿汉式,需要的时候再创建唯一实例;3,注册式,spring里配置一个单例的对象使用的就是这种方式;

    个人工作当中用到的单例模式,主要是Servlet,所有的servlet都是单例的,工作方式如下:

    Servlet容器默认是采用单实例多线程的方式处理多个请求的:

    
    

    1.      当web服务器启动的时候(或客户端发送请求到服务器时),Servlet就被加载并实例化(只存在一个Servlet实例);

    
    

    2.      容器初始化Servlet。主要就是读取配置文件(例如tomcat,可以通过servlet.xml的<Connector>设置线程池中线程数目,初始化线程池;通过web.xml,初始化每个参数值等等);

    
    

    3.      当请求到达时,Servlet容器通过调度线程(Dispatchaer Thread)调度它管理下的线程池中等待执行的线程(Worker Thread)给请求者;

    
    

    4.      线程执行Servlet的service方法;

    
    

    5.      请求结束,放回线程池,等到被调用;

     

    3.2  原型模式

      通过复制来创建对象;

    类别 详细
    简介 通过给出一个原型对象来指明所有要创建的对象类型,然后用复制这个原型对象来创建更多的对象。
    参考 http://www.cnblogs.com/java-my-life/archive/2012/04/11/2439387.html
    实例分析

    package com.lifc.year.end.design.pattern.creation.prototype;

    import java.io.Serializable;

    public class Stick implements Serializable {

    private static final long serialVersionUID = 7469022367218217983L;

    final float rate = 0.2f;

    private String name;

    private float height = 1.5f;

    private float radius = 0.1f;

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public float getHeight() {
    return height;
    }

    public void setHeight(float height) {
    this.height = height;
    }

    public float getRadius() {
    return radius;
    }

    public void setRadius(float radius) {
    this.radius = radius;
    }

    public void zoom() {

    this.height *= (1 + rate);
    this.radius *= (1 + rate);
    }

    public void lessen() {
    this.height *= (1 - rate);
    this.radius *= (1 - rate);
    }

    @Override
    public String toString() {
    return getName()+",长---"+getHeight()+"米--- ,直径---"+getRadius();
    }

    }


    package com.lifc.year.end.design.pattern.creation.prototype;

    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.ObjectInput;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.OutputStream;
    import java.io.Serializable;

    public class Monkey implements Cloneable, Serializable {

    private static final long serialVersionUID = 8983410453711474678L;

    private String name;

    private String hat;

    private Stick jiGuBang;

    private String cloth;

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public String getHat() {
    return hat;
    }

    public void setHat(String hat) {
    this.hat = hat;
    }

    public Stick getJiGuBang() {
    return jiGuBang;
    }

    public void setJiGuBang(Stick jiGuBang) {
    this.jiGuBang = jiGuBang;
    }

    public String getCloth() {
    return cloth;
    }

    public void setCloth(String cloth) {
    this.cloth = cloth;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {

    return (Monkey)super.clone();
    }

    public Monkey deepClone()
    {
    ByteArrayOutputStream os=new ByteArrayOutputStream();
    try {
    ObjectOutputStream oos=new ObjectOutputStream(os);
    oos.writeObject(this);
    InputStream is=new ByteArrayInputStream(os.toByteArray());
    ObjectInputStream ois=new ObjectInputStream(is);

    return (Monkey)ois.readObject();

    } catch (IOException e) {
    e.printStackTrace();
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }

    return null;
    }

    }

    package com.lifc.year.end.design.pattern.creation.prototype;

    public class Client {
    public static void main(String[] args) {

    Stick stick=new Stick();
    stick.setName("如意金箍棒");

    Monkey monkey=new Monkey();
    monkey.setName("孙悟空");
    monkey.setCloth("裂地穿云甲");
    monkey.setHat("凤劈紫金冠");
    monkey.setJiGuBang(stick);

    System.out.println("真身: "+monkey.getName()+","+monkey.getHat()+" ,"+monkey.getCloth()+" ,"+monkey.getJiGuBang().toString());


    try {
    Monkey fenshen=(Monkey)monkey.clone();


    System.out.println("分身1:浅复制 "+fenshen.getName()+","+fenshen.getHat()+" ,"+fenshen.getCloth()+" ,"+fenshen.getJiGuBang().toString());

    } catch (CloneNotSupportedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    Monkey fenshen2=monkey.deepClone();
    fenshen2.getJiGuBang().zoom();
    System.out.println("分身2:深复制 "+fenshen2.getName()+","+fenshen2.getHat()+" ,"+fenshen2.getCloth()+" ,"+fenshen2.getJiGuBang().toString());

    System.out.println("真身: "+monkey.getName()+","+monkey.getHat()+" ,"+monkey.getCloth()+" ,"+monkey.getJiGuBang().toString());
    }

    }

     
    说明
    实例通过孙悟空扯几根毛身外化身的例子来反映原型模式的应用;

    克隆必须满足的条件:
    a.对任何的对象x,都有:x.clone() != x,即克隆对象与原对象不是同一个对象。
    b.对任何的对象x,都有:x.clone().getClass() == x.get getClass(),即克隆对象与原对象的类型是一样的。 c.如果对象x的equals()方法定义恰当的话,那么x.clone().equals(x)应当是成立的。
    在java中实现clone()应该满足这三个条件。

    浅复制:复制了值类型对象,对于引用类型对象,只复制了引用,它指向原来引用的对象。Java中clone为浅复制。
    深复制:对值类型和引用类型的对象都生成一份新的拷贝. Java中可以通过串行化来进行深复制,前提是对象以及对象内部所引用的对象都是可串行化的,否则需要考虑将那些不可串行化的对象可否设为transient,排除 在复制过程之外。

    适用于创建对象比较困难的环境;

    3.3  建造者模式

      表示和构建分离;

    类别 详细
    简介 将一个对象的表示和构建分离,使得同样的构建过程可以创建不同的表示;
    实例分析

    package com.lifc.year.end.design.pattern.creation.build;

    public interface Builder {

    public void installCPU();

    public void installMemory();

    public void installMotherBoard();

    public void installHardDisk();

    public void installMonitor();

    public void installSystem();
    }

    package com.lifc.year.end.design.pattern.creation.build;

    public class TableBuilder implements Builder {

    @Override
    public void installCPU() {
    System.out.println("安装Inter I3 处理器");

    }

    @Override
    public void installMemory() {
    System.out.println("安装DDR3 8G 内存");

    }

    @Override
    public void installMotherBoard() {
    System.out.println("安装最新的技嘉主板 ");

    }

    @Override
    public void installHardDisk() {
    System.out.println("安装三星固态硬盘 ");
    }

    @Override
    public void installMonitor() {
    System.out.println("安装20寸液晶显示器 ");

    }

    @Override
    public void installSystem() {
    System.out.println("安装win8系统");

    }

    }

    package mode.creation.build;

    public class Director {

    private Builder builder;

    public Director(Builder builder)
    {
    this.builder=builder;
    }


    public void build()
    {
    System.out.println("安装台式机的过程....");
    System.out.println("1,把主板装到主机箱里...");
    builder.installMotherBoard();
    System.out.println("2,把处理器装到主板上...");
    builder.installCPU();
    System.out.println("3,把内存装到主板上...");
    builder.installMemory();
    System.out.println("4,把硬盘装到机箱里...");
    builder.installHardDisk();
    System.out.println("5,装好机箱,连接显示器...");
    builder.installMonitor();
    System.out.println("6,接上电源安装系统...");
    builder.installSystem();

    }
    }

    package mode.creation.build;

    import mode.creation.build.Director;

    public class Client {

    public static void main(String[] args) {

    Director director=new Director(new TableBuilder());

    director.build();

    }

    }

    
    
    说明
    实例装配台式机的例子来展示建造者模式;

    在工作当中,比如封装jdbc的底层操作的时候,使用了这个模式,把相同的操作代码,比如打开连接和关闭连接,验证参数的代码放到方法当中,不同的执行sql,获取结果集的操作写成抽象方法,放到子类实现,访问过程独立一些基本代码;

    3.4 工厂方法模式

      创建对象延迟到之类;

      

    类别 详细
    简介 定义一个用户创建对象的接口,让子类决定实例化哪个类,工厂方法使得一个类的实例化延迟到子类中来;
    参考 http://blog.csdn.net/yuan22003/article/details/6709649
    实例分析

    手写例子:最近想买个电脑,考虑dell和apple,利用工厂方法模式模拟一下得到电脑的过程如下:
    package com.lifc.year.end.design.pattern.creation.factorymethod;

    public interface Computer {

    public void self();

    }

    package com.lifc.year.end.design.pattern.creation.factorymethod;

    public class Dell implements Computer {

    @Override
    public void self() {

    System.out.println("dell 电脑,inter 芯片,高端享受···");

    }

    }

    package com.lifc.year.end.design.pattern.creation.factorymethod;

    public class Apple implements Computer {

    @Override
    public void self() {

    System.out.println(" apple 电脑,jobs设计,体验极致···");

    }

    }

    package com.lifc.year.end.design.pattern.creation.factorymethod;

    public interface ComputerFactory {

    public Computer getComputer();

    }

    package com.lifc.year.end.design.pattern.creation.factorymethod;

    public class AppleComputerFactory implements ComputerFactory {

    @Override
    public Computer getComputer() {
    return new Apple();
    }

    }

    package com.lifc.year.end.design.pattern.creation.factorymethod;

    public class DellComputerFactrory implements ComputerFactory {

    @Override
    public Computer getComputer() {
    return new Dell();
    }

    }

    package com.lifc.year.end.design.pattern.creation.factorymethod;

    public class Client {

    /**
    * 创建时间: 2013-1-28 上午11:29:47
    * 创建人:cutter.li
    * 参数:
    * 返回值: void
    * 方法描述 :
    */
    public static void main(String[] args) {

    System.out.println(" I want by a apple Computer ...");

    ComputerFactory computerFactory=new AppleComputerFactory();

    Computer apple=computerFactory.getComputer();

    System.out.println(" get a computer ,it is information ...");

    apple.self();

    }

    }

    
    
    说明
    总的感觉是面对需求变更,1,扩展容易,不会影响之前的功能,但是需要创建太多的类,2,需要变更客户端代码;(如果不想修改代码,可以通过反射机制,修改配置文件)

    3.5 抽象工厂模式

      创建一些列产品族的模式;

    类别 详细
    简介 提供一个创建一系列相关或者相互依赖对象的接口,无需制定他们的具体类;
    参考 比较好的例子:http://gengu.iteye.com/blog/1125260
    实例分析

    手写例子:组装电脑,使用不同平台的cup,主板,内存等的例子:

    
    
    说明
    可灵活适应变化,但是类增加的太多了

    4,横向对比

      五种创建型模式,各有优劣,分别适合不同的场景。

  • 相关阅读:
    (转载)MySQL日期时间函数大全
    Tcl commands
    Toplevel
    tk 8.4 commands
    iwidgets
    Options for Buttontype widgets
    Text Widget Options
    tk options
    itk_option
    Widget Options
  • 原文地址:https://www.cnblogs.com/snidget/p/2892139.html
Copyright © 2011-2022 走看看