Factory:

●简介:

工厂模式同单例模式一样,也是Java中最常用的设计模式之一,属于创建型模式,它提供了一种创建对象的最佳方式。能够根据要求调用者提供的信息为接口指定不同的实现类,降低耦合。

●接口及其实现类

package factory;

public interface Sender {
public void send();
}
package factory;

public class SmsSender implements Sender{

    @Override
public void send() {
System.out.println("用短信发送...");
}
}
package factory;

public class EmailSender implements Sender{

    @Override
public void send() {
System.out.println("用电子邮箱发送...");
}
}

●简单工厂

package factory;
/**
* 普通工厂模式,可以需求生产对象
* 缺点:面对复杂的初始化,会使代码变得巨大
* 每添加一个实现类都要修改代码,违反了里氏替换原则
* 可能会产生null对象,引发 空指针异常
* @author wqj24
*
*/
public class GeneraSenderFactory { public Sender produceSender(String msg) { // 根据消息,指定具体实现类
if ("email".equals(msg)) {
return new EmailSender();
} if ("sms".equals(msg)) {
return new SmsSender();
} // 没有符合要求的产品
return null;
}
}

上面的缺点就是,每写添加一个实现类就要改工厂类的代码,我们可以通过反射解决这一痛点。

●简单工厂(反射)

package factory;
/**
* 简单工厂的优化
* 优点:使用反射,避免了添加子类就要修改工厂对象
*/
public class GeneraSenderFactory01 { public Sender produceSender(Class<? extends Sender> clazz) { Sender sender = null; try {
sender = (Sender) clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} return sender;
}
}

如果面对初始化复杂的对象,上面那的代码会变得很长,结构性差,可以为每个子类都写一个工厂方法。

●多个工厂方法

package factory;

/**
* 多工厂,每个方法负责生产各自的实例 优点可以应对复杂的初始化
* 优点:不会产生 null 对象
* 每个方法负责自己对象的初始化工作,结构清晰。
*/
public class ManySenderFactory { public Sender produceEmail() { return new EmailSender();
} public Sender produceSms() { return new SmsSender();
}
}

也可以将上面的方法改写成静态的,这样就可以不用new对象,直接通过类名调用工厂方法了。

Singleton:

  • 单例模式,确保某个类只能生成一个实例
  • 单例模式的构造方法必须定义为私有(private)的
  • 必须要定义一个静态(static)的方法,作为生成这个对象实例的入口
package com.singleton;
//静态代码块不一定在最开始执行,比如说 静态代码块 放在 单例模式中,
//但一般情况下 静态代码块是第一执行的 也就是在类加载时执行, 只执行一次
class SingletonTest
{
private static SingletonTest singletonTest = new SingletonTest();
static
{
System.out.println("======java 静态代码块========");
} private SingletonTest()
{
System.out.println("java实现单例模式");
} public static SingletonTest getInstance()
{ return singletonTest;
} } public class Singleton
{
public static void main(String[] args)
{
SingletonTest st = SingletonTest.getInstance();
SingletonTest st2 = SingletonTest.getInstance(); //返回true,这两个实例是一样的
System.out.println(st == st2);
}

prototype:

  原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。本小结会通过对象的复制,进行讲解。在Java中,复制对象是通过clone()实现的,先创建一个原型类:

public class Prototype implements Cloneable {  

    public Object clone() throws CloneNotSupportedException {
Prototype proto = (Prototype) super.clone();
return proto;
}
}

  很简单,一个原型类,只需要实现Cloneable接口,覆写clone方法,此处clone方法可以改成任意的名称,因为Cloneable接口是个空接口,你可以任意定义实现类的方法名,如cloneA或者cloneB,因为此处的重点是super.clone()这句话,super.clone()调用的是Object的clone()方法,而在Object类中,clone()是native的,具体怎么实现,我会在另一篇文章中,关于解读Java中本地方法的调用,此处不再深究。在这儿,我将结合对象的浅复制和深复制来说一下,首先需要了解对象深、浅复制的概念:

  浅复制:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。

  深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。

proxy:

动态代理(运行期行为)主要有一个 Proxy类 和一个 InvocationHandler接口

动态代理角色:

1. 抽象主题角色

2. 真实主题角色(实现了抽象主题接口)

3. 动态代理主题角色(实现了 InvocationHandler接口,并实现了 invoke()方法)

Proxy 要调用 newProxyInstance方法

代码演示:

1.抽象主题角色 SubjectDemo.java

package com.dynamicproxy ;  

public interface SubjectDemo
{
public void request() ;
}

2. 真实主题角色 RealSubjectDemo.java

package com.dynamicproxy ;  

public class RealSubjectDemo implements SubjectDemo
{
public void request()
{
System.out.println("实现了某请求") ;
}
}

3. 动态代理主题角色 DynamicProxySubjectDemo.java

package com.dynamicproxy ;  

import java.lang.reflect.InvocationHandler ;
import java.lang.reflect.Method ; public class DynamicProxySubjectDemo implements InvocationHandler
{
private Object sub ; public DynamicProxySubjectDemo(Object obj)
{
this.sub = obj ;
} public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
System.out.println("before"+method) ; method.invoke(sub, args) ;//真实的调用方法操作 System.out.println("after"+method) ; return null ; } }
 

4.客户端 Client.java

package com.dynamicproxy ;  

import java.lang.reflect.InvocationHandler ;
import java.lang.reflect.Proxy ; public class Client
{
public static void main(String[] args)
{
RealSubjectDemo rsd = new RealSubjectDemo() ; InvocationHandler handler = new DynamicProxySubjectDemo(rsd) ; Class<?> classType = handler.getClass() ; // classType.getClassLoader() 动态代理类的类加载器
//rsd.getClass().getInterfaces() 代理类要实现的接口列表
//handler 指派方法调用的调用处理程序
SubjectDemo sd = (SubjectDemo)Proxy.newProxyInstance(classType.getClassLoader(), rsd.getClass().getInterfaces(), handler ) ; //这行代码一执行 转到 InvocationHandler handler = new DynamicProxySubjectDemo(rsd)
//执行invoke方法
sd.request() ;
}
}

Java Design Patterr的更多相关文章

  1. [Java] Design Pattern:Code Shape - manage your code shape

    [Java] Design Pattern:Code Shape - manage your code shape Code Shape Design Pattern Here I will intr ...

  2. java design pattern - adapter pattern

    场景 适配器模式 总结 参考资料 场景 在编程中我们经常会遇到驴头不对马嘴的情况,比如以前是继承A的接口的对象,现在外部调用的时候需要该对象已B接口的形式来调用 ,这个时候我们可以让对象同时集成A和B ...

  3. SOLID rule in JAVA design.

    Classes are the building blocks of your java application. If these blocks are not strong, your build ...

  4. java Design Patterns

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  5. Java Design Pattern(Factory,Singleton,Prototype,Proxy)

    一.Factory 设计模式: the most common pattern,create a new object ,eg. A a=new A();工厂模式的好处:工厂模式可以做到把创建对象单独 ...

  6. Java Design Patterns(2)

    1.Factory Design pattern 工厂设计模式的优点 (1)工厂设计模式提供了接口而不是实现的代码方法. (2)工厂模式从客户端代码中删除实际实现类的实例化.工厂模式使我们的代码更健壮 ...

  7. Java Design Demo -简单的队列-异步多任务队列(java android)

    简单的单线程队列 -- 工作的时候遇到劣质打印机.给打印机发消息,打印机就会打印,如果在打印机还在打印的时候,就 再发消息打印,就会出现消息丢失.所以需要给上一个任务一些处理的间隔时间. 单线程的消息 ...

  8. JAVA DESIGN PATTERN

    工厂模式(factory) 简单工厂模式的概念 就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建.简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承 ...

  9. analysed of J-SON/XML processing model Extend to java design model (J-SON/XML处理模型分析 扩展到Java设计模型 )

    一.JSON和XML 1.JSON JSON(JavaScript Object Notation)一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性.可在不同平台之间进行数据交换.JSON ...

随机推荐

  1. OO第二单元作业分析

    前言 这一单元关于线程安全的作业结束了,在助教提供的接口的帮助以及老师提供的设计模型的指导下,这三次作业还是相对轻松地完成了,中间也没有出现什么bug,可能就是因为简单的逻辑不容易出错吧,可惜两次都由 ...

  2. linux下用ctrl+r快速搜索history命令

    前提是,搜索已经使用的命令,否则是查不出来结果的. ctrl+r用途:反向搜索执行过的命令.(reverse-i-search) 1.任何目录下按住ctrl + r 2.输入历史命令中的字符串 ,比如 ...

  3. Linux主机安全配置规范

    一.账号口令 1 配置口令最小长度     在文件/etc/login.defs中设置 PASS_MIN_LEN,参考值:8 2 配置口令生存周期     在文件/etc/login.defs中设置 ...

  4. 利用类的反射导入excel示例

    直接上代码 1.页面展示 <div class="panel-heading font-bold text-center"> <i class="fa ...

  5. Inno Setup打包带有MSI文件的程序

    [Setup] ; 注: AppId的值为单独标识该应用程序. ; 不要为其他安装程序使用相同的AppId值. ; (生成新的GUID,点击 工具|在IDE中生成GUID.) AppId={{47A1 ...

  6. Handlebars.js registerHelper

    Handlebars.registerHelper('link', function (text, url) { text = Handlebars.Utils.escapeExpression(te ...

  7. MySQL面试题中:主从同步部署介绍

    主从同步部署1.两台相同版本的mysql数据库,一台做主库,一台从库 主库开启binlog 在配置文件中的[mysqld]模块中添加log-bin=mysql-bin和server-id=1,一定要保 ...

  8. ORC 文件存储格式

    1.orc列式存储概念 a)列式存储:orc并不是纯粹的列式存储,也是先基于行对数据表进行分组(行组),然后对行组进行列式存储. b)查询数据的时候不需要扫描全部数据(磁盘IO),只需查询指定列即可. ...

  9. MapReduce作业的工作原理

    在Hadoop中,我们可以通过Job对象的submit()方法来运行MapReduce作业,也可以调用waitForCompletion()用于提交以前没有提交过的作业,并等待它的完成.其中,subm ...

  10. flask教程

    http://docs.jinkan.org/docs/flask/ https://dormousehole.readthedocs.io/en/latest/ https://m.w3cschoo ...