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. SQL学习 存储过程&DUAL表

    CREATE OR REPLACE PROCEDURE 存储过程 转自 https://www.cnblogs.com/lideng/p/3427822.html oracle中dual表的用途介绍 ...

  2. javascript 创建节点和新增节点

    createElement(tabName) 创建一个为tagName的新元素节点 ANode.appendChild(BNode)把B节点追加至A节点的末尾 insertBefore(ANode,B ...

  3. 关于WebService

    转自于:https://www.cnblogs.com/xdp-gacl/p/4048937.html 一.序言 大家或多或少都听过 WebService(Web服务),有一段时间很多计算机期刊.书籍 ...

  4. Assembly Experiment9

    用英文写太浪费时间了,而且书上的讲解对各种功能的英文原句少之又少,有空还是看龙书吧(不存在的) 实验1: 十六进制转换十进制 实验代码: ; 在屏幕上输出内存单元中的十进制两位数 assume cs: ...

  5. day-10初级函数

    函数 函数的定义 函数:完成 特定 功能的代码块,作为一个整体,对其进行特定的命名,该名字就代表函数-- 现实中:很多问题要通过一些工具进行处理 => 可以将工具提前生产出来并命名=> 通 ...

  6. idea构建maven多项目web架构

    1.新建一个maven项目作为顶级module,可以使用模板quickstart模板,在生成pom.xml中添加一些子项目都会用到的依赖,apache-commons,guava等.因为是顶级modu ...

  7. C语言之一维数组与指针

    一维数组: 假如有一维数组如下: ]; 该数组有3个元素,数据类型为char型,地址空间如下. 如果想访问数据,直接使用a[0].a[1].a[2]取出相应地址空间的值即可 一级指针: 指针即地址,c ...

  8. html限制文本框只能输入数字和一个小数点

    近期在做一个前台页面,有一个文本框是用来输入充值金额的,就想到了限制用户只能输入纯数字的数据且只能包含一个小数点.下面就是我实现的代码 $(function() { //阻止数字键以外的按键输入 $( ...

  9. 为服务器设置SSL证书,配置Https协议

    注意 服务器要打开443端口 1.申请证书,这里推荐腾讯云或者阿里云的,有免费的证书,要求不高的盆友可以试一试 2.打开php.ini扩展. extension=php_openssl.dll 3.打 ...

  10. css 优化

    // 注: 以下内容大量借阅自<<Webkit技术内幕>>--朱永盛(14年出版的) , 很多内容可能早已更新 , 因此个人并不能确定论述是否正确.部分摘录内容有删减 , 目录 ...