乐趣区

关于java:原型模式

目录

  • 定义
  • 实现
  • 应用场景

定义

应用原型实例创建对象实例,而后通过拷贝这些原型来创立新的对象。

在 java 中次要是通过原型实现 Cloneable 接口,而后又应用 clone 办法来复制这个原型实例给客户端,从而实现原型模式的目标。

那么这么做有什么益处呢?创立一个对象的次要就是申请内存 + 成员变量赋值,在零碎中这点开销是能够疏忽不记的,所以个别常见也不倡议应用原型模式。然而如果在每次创建对象的时候都须要进行加载文件、加解密等操作,这些操作须要消耗大量的工夫和资源,而且每次加载的内容都差不多,那么此时咱们能够思考应用原型模式。

实现

上面咱们通过一个创立数据库连贯的类来体验一下原型模式的实现,首先是有一个数据库的配置文件外面有主从节点的配置,咱们要加载相干配置文件,而后通过复制的形式将连贯类实例返回给客户端。

主从节点的配置文件 config.properties

master.ip=localhost
master.port=3306
master.username=root
master.password=123456
master.type=mysql

slave.ip=localhost
slave.port=3307
slave.username=root
slave.password=123456
slave.type=mysql

Connection – 所有数据库连贯的父类实现了连贯类的次要工作比方加载主配置文件

MasterConnection & SlaveConnection – 细化了不同节点的数据库连贯并且实现了原型复制

public abstract class Connection implements Cloneable {
    protected static Properties properties;
    static {properties = new Properties();
        InputStream in = null;
        try {in = new FileInputStream("config.properties");
            properties.load(in);
        } catch (IOException e) {e.printStackTrace();
        }finally {
            try {
                assert in != null;
                in.close();} catch (IOException e) {e.printStackTrace();
            }
        }
    }

    private String ip;
    private String port;
    private String username;
    private String password;
    private String type;

    public String getIp() {return ip;}

    void setIp(String ip) {this.ip = ip;}

    public String getPort() {return port;}

    void setPort(String port) {this.port = port;}

    public String getUsername() {return username;}

    void setUsername(String username) {this.username = username;}

    public String getPassword() {return password;}

    void setPassword(String password) {this.password = password;}

    public String getType() {return type;}

    void setType(String type) {this.type = type;}

    @Override
    protected Object clone() throws CloneNotSupportedException {return super.clone();
    }
}
public class MasterConnection extends Connection{private static final Connection CONNECTION = new MasterConnection();
    static {CONNECTION.setIp(properties.getProperty("master.ip"));
        CONNECTION.setPort(properties.getProperty("master.port"));
        CONNECTION.setUsername(properties.getProperty("master.username"));
        CONNECTION.setPassword(properties.getProperty("master.password"));
        CONNECTION.setType(properties.getProperty("master.type"));
    }

    public static Connection getConnection() throws CloneNotSupportedException {return (Connection)CONNECTION.clone();}
}
public class SlaveConnection extends Connection{private static final Connection CONNECTION = new SlaveConnection();
    static {CONNECTION.setIp(properties.getProperty("slave.ip"));
        CONNECTION.setPort(properties.getProperty("slave.port"));
        CONNECTION.setUsername(properties.getProperty("slave.username"));
        CONNECTION.setPassword(properties.getProperty("slave.password"));
        CONNECTION.setType(properties.getProperty("slave.type"));
    }

    public static Connection getConnection() throws CloneNotSupportedException {return (Connection)CONNECTION.clone();}
}

测试

public class PrototypeTest {
    @Test
    public void test(){
        try {Connection connection = MasterConnection.getConnection();
            System.out.println(connection.getPort());
            connection = SlaveConnection.getConnection();
            System.out.println(connection.getPort());
        } catch (CloneNotSupportedException e) {e.printStackTrace();
        }
    }
}
======= 后果 =======
3306
3307

应用场景

  • 资源优化场景:创建对象时须要初始化大量的内部资源
  • 简单依赖场景:须要创立的对象 A 依赖于对象 B 和对象 C,对象 B 又依赖于对象 D …..
  • 同一个对象会被多个批改者应用的场景:一个商品可能会给订单、物流、会员多个服务应用批改
  • 须要保留原始状态的场景:就比方下面的 Connection 类,咱们须要保留从文件中加载的配置
退出移动版