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. 编译原理作业(第一次)-完成retinf.c(阉割版)

    首先,作业要求概括如下: 根据前缀表达式文法,实现statements() 和expression() 两个函数. 并且要求使得语义分析在完成分析前缀表达式并输出中间代码的同时,也能够将前缀表达式翻译 ...

  2. Linux第六节课学习笔记

    if条件测试语句可以让脚本根据实际情况自动执行相应的命令,可以分为单分支.双分支与多分支. /dev/null为无回收功能的垃圾箱. read是用来读取用户输入信息的命令,-p用来显示提示信息. fo ...

  3. 用shell脚本创建sqlite表并添加sql语句--通用

    重要使用的是EOF的功能,亲测和!功能一致:下面是测试代码 #!/bin/bash val=`ls`for v in ${val} do if [ ${v} == "test.db" ...

  4. Vue通过路由 query传递参数

    父组件通过query来传递num参数为1,相当与在 url 地址后面拼接参数 <template> <div> <h3>首页</h3> <rout ...

  5. devC++代码格式化对齐的快捷键

    devC++代码格式化对齐的快捷键是ctrl + shift + a ctrl + 左右键可以使光标移动一个单词的距离 shirt + 左右键可以选中光标左右的一个字符

  6. Git-命令行-删除本地和远程分支

    命令行方式 Git Bash: 切换到要操作的项目文件夹 命令行 : $ cd <ProjectPath> 查看项目的分支们(包括本地和远程) 命令行 : $ git branch -a ...

  7. H5外包 微信小程序外包 小程序外包 就找北京动点开发团队

    长年承接微信小程序.微信公众号开发 全职的H5开发团队,开发过几十款微信小程序公众号案例 欢迎来电咨询 QQ:372900288 微信:liuxiang0884 TEL:13911652504

  8. django 防止xss攻击标记为安全的二种方法

    str='<a href="/page?page=1">1</a>' 一,在前端模板语言中实现,只须用到帮助函数safe.如: {{ str|safe }} ...

  9. python3-基础5

    #函数 1 什么是函数? 2 为什么要用函数? 3 函数的分类:内置函数与自定义函数 4 如何自定义函数 5 语法 6 定义有参数函数,及有参函数的应用场景 7 定义无参数函数,及无参函数的应用场景 ...

  10. JavaScript 对象属性底层原理

    对象属性类型 1. 数据属性 [[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,特性默认值为true [[Enum ...