java之设计模式
一、代理模式
//接口
public interface UserDAO {
public void add();
}
//真实角色
public class UserDaoImpl implements UserDAO{
public void add() {
System.out.println("添加数据");
}
}
//代理角色
public class UserDaoImplProxy implements UserDAO{
private UserDaoImpl userDaoImpl;
public UserDaoImplProxy(UserDaoImpl userDaoImpl) {
super();
this.userDaoImpl = userDaoImpl;
}
public void add() {
log();
userDaoImpl.add();
System.out.println("========>add()");
}
private void log(){
System.out.println("添加日志");
}
}
2.动态代理
动态代理:在程序运行时,运用反射机制动态创建而成。
jdk提供的动态代理
public interface UserDAO {
public void addUser();
public void updateUser();
} public class UserDaoImpl implements UserDAO {
public void addUser() {
System.out.println("添加用户");
}
public void updateUser() {
System.out.println("更新用户");
}
} public class UserLog {
public static void beginLog(String methodName ){
System.out.println(methodName+"方法,开始执行");
}
} public class ProxyHandler implements InvocationHandler {
private Object proxyObject;//
public ProxyHandler(Object proxyObject){
this.proxyObject=proxyObject;
}
/**
* Object proxy:指被代理的对象。
* Method method:要调用的方法
* Object[] args:方法调用时所需要的参数
*/
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println("proxy:"+proxy.getClass().getName());
System.out.println("method:"+method.getName());
System.out.println("args:"+args);
UserLog.beginLog(method.getName());
Object object=method.invoke(proxyObject, args);//普通的Java反射代码,通过反射执行某个类的某方法
return object;
}
} public class TestProxy {
public static void main(String[] args) {
testProxy();
}
private static void testProxy(){
UserDaoImpl userDaoImpl=new UserDaoImpl();//元对象(被代理对象)
ProxyHandler invocationHandler =new ProxyHandler(userDaoImpl);//代理实例的调用处理程序。
//创建一个实现业务接口的代理类,用于访问业务类(见代理模式)。
//返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序,如ProxyHandler。
UserDAO userDAO= (UserDAO)Proxy.newProxyInstance(
userDaoImpl.getClass().getClassLoader(),userDaoImpl.getClass().getInterfaces(),
invocationHandler);
//调用代理类方法,Java执行InvocationHandler接口的方法.
userDAO.addUser();
}
}
二、单例模式
确保一个类只有一个对象
package com.jalja.jdk17.Polymorphic;
/**
*
* 懒汉式
* 构造器 私有化,避免外部创建对象
* 声明一个私有的静态变量
* 创建一个对外公开的静态方法访问该变量,如果没有变量,创建对象
*
*/
public class JVM {
private static JVM instance=null;
private JVM(){ }
public static JVM getInstances(){
if(instance==null){
synchronized (JVM.class) {
if(instance==null){
instance=new JVM();
}
}
}
return instance;
}
}
三、策略模式
定义:策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。
策略模式的组成:
抽象策略角色:策略类,通常由一个接口或者抽象类实现。
具体策略角色:包装了相关的算法和行为。
环境角色:持有一个策略类的引用,最终给客户端用的。
优点:
1、 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
缺点:
1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
2、 在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。(这本身没有解除客户端需要选择判断的压力,
而策略模式与简单工厂模式结合后,选择具体实现的职责也可以由Context来承担,这就最大化的减轻了客户端的压力。)
//抽象策略角色:策略类, 给出所有的具体策略类所需的接口(给具体策略类一个方向)。
public interface Strategy {
public int calculate(int a,int b);
} //具体的策略类 一:求和
public class AddStrategy implements Strategy {
public int calculate(int a, int b) {
return a+b;
}
} //具体 策略类三:相乘
public class MultiplyStrategy implements Strategy{
public int calculate(int a, int b) {
return a*b;
}
} //具体的策略类 二:相减
public class SubtractStrategy implements Strategy{
public int calculate(int a, int b) {
return a-b;
}
} //环境角色,持有Strategy接口的引用,并且有get和set方法可以完成策略更换。在环境角色中调用接口的方法完成动作。
public class Environment {
private Strategy strategy;
public Environment(Strategy strategy) {
super();
this.strategy = strategy;
}
public Strategy getStrategy() {
return strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public int calculate(int a, int b){
return strategy.calculate(a, b);
}
//测试
public static void main(String[] args) {
// 调用 AddStrategy 求和
Strategy addStrategy=new AddStrategy();
Environment environment1=new Environment(addStrategy);
System.out.println("求和====》"+environment1.calculate(5, 10));
// 调用 AddStrategy 求积
Strategy multiplyStrategy=new MultiplyStrategy();
Environment environment2=new Environment(multiplyStrategy);
System.out.println("求积===》"+environment2.calculate(5, 10));
// 调用 AddStrategy 求差
Strategy subtractStrategy=new SubtractStrategy();
Environment environment3=new Environment(subtractStrategy);
System.out.println("求差====》"+environment3.calculate(5, 10));
}
}
四、简单工厂模式
定义:简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。
package com.jalja.jdk7.test.ms;
//抽象策略角色:策略类, 给出所有的具体策略类所需的接口(给具体策略类一个方向)。
public interface Strategy {
public int calculate(int a,int b);
} package com.jalja.jdk7.test.ms;
//具体的策略类 一:求和
public class AddStrategy implements Strategy {
public int calculate(int a, int b) {
return a+b;
}
} package com.jalja.jdk7.test.ms;
//具体的策略类 二:相减
public class SubtractStrategy implements Strategy{
public int calculate(int a, int b) {
return a-b;
}
} package com.jalja.jdk7.test.ms;
//具体 策略类三:相乘
public class MultiplyStrategy implements Strategy{
public int calculate(int a, int b) {
return a*b;
}
} package com.jalja.jdk7.test.ms;
import sun.org.mozilla.javascript.internal.Evaluator; //环境角色,持有Strategy接口的引用,并且有get和set方法可以完成策略更换。在环境角色中调用接口的方法完成动作。
public class Environment {
private Strategy strategy;
public Environment(Strategy strategy) {
super();
this.strategy = strategy;
}
public Strategy getStrategy() {
return strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public int calculate(int a, int b){
return strategy.calculate(a, b);
}
}
package com.jalja.jdk7.test.ms; public class StrategyFactory {
private static Strategy strategy;
public static Strategy getStrategyChile(String objStr){
if(objStr.equalsIgnoreCase("addStrategy")){
strategy=new AddStrategy();
}
if(objStr.equalsIgnoreCase("multiplyStrategy")){
strategy=new MultiplyStrategy();
}
if(objStr.equalsIgnoreCase("subtractStrategy")){
strategy=new SubtractStrategy();
}
return strategy;
}
//利用反射
public static Strategy getStrategyChile2(String type){
try {
strategy=(Strategy) Class.forName("com.jalja.jdk7.test.ms."+type).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return strategy;
}
//测试
public static void main(String[] args) {
// 调用 AddStrategy 求和
Environment environment1=new Environment(StrategyFactory.getStrategyChile2("AddStrategy"));
System.out.println("求和====》"+environment1.calculate(5, 10));
// 调用 AddStrategy 求积
Environment environment2=new Environment(StrategyFactory.getStrategyChile2("MultiplyStrategy"));
System.out.println("求积===》"+environment2.calculate(5, 10));
// 调用 AddStrategy 求差
Environment environment3=new Environment(StrategyFactory.getStrategyChile2("SubtractStrategy"));
System.out.println("求差====》"+environment3.calculate(5, 10));
}
}
五、观察者模式
定义:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。
这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己。
组成:
抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,
可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
具体主题角色: 在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。
具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。
如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。
//抽象观察者角色
public interface Watcher {
public void update(String str);
} //抽象主题角色,watched:被观察
public interface Watched {
public void addWatcher(Watcher watcher);
public void removeWatcher(Watcher watcher);
public void notifyWatchers(String str);
} //具体的观察者
public class ConcreteWatcher implements Watcher{
private String name;
public ConcreteWatcher(String name) {
super();
this.name = name;
}
public void update(String str) {
System.out.println(name+"收到更新的消息=====》"+str);
}
} //具体的主题角色:
public class ConcreteWatched implements Watched{
// 存放观察者
private List<Watcher> list = new ArrayList<Watcher>();
public void addWatcher(Watcher watcher) {
list.add(watcher);
}
public void removeWatcher(Watcher watcher) {
list.remove(watcher);
}
public void notifyWatchers(String str) {
// 自动调用实际上是主题进行调用的
for (Watcher watcher : list)
{
watcher.update(str);
}
}
} //测试
public class Test {
public static void main(String[] args) {
Watched girl = new ConcreteWatched();//定义主题
//创建观察者
Watcher watcher1 = new ConcreteWatcher("男一号");
Watcher watcher2 = new ConcreteWatcher("男二号");
Watcher watcher3 = new ConcreteWatcher("男三号");
//主题添加观察者
girl.addWatcher(watcher1);
girl.addWatcher(watcher2);
girl.addWatcher(watcher3);
//主题产生最新消息
girl.notifyWatchers("开心");
}
}
优点
- 支持松耦合和减少依赖性。客户端不再依赖于观察器,因为通过使用主体和 Observer 接口对客户端进行了隔离。许多框架具有此优点,在这些框架中的应用程序组件可以注册为当(低级)框架事件发生时得到通知。结果,框架将调用应用程序组件,但不会依赖于它。
- 观察器数目可变。观察器可以在运行时附加和分离,因为主体对于观察器数目没有任何假定。此功能在这样的情况下是很有用的:观察器数在设计时是未知的。例如,如果用户在应用程序中打开的每个窗口都需要一个观察器。
缺点
- 性能降低。在许多实现中,观察器的 update() 方法可能与主体在同一线程中执行。如果观察器列表很长,则执行 Notify() 方法可能需要很长时间。抽取对象依赖性并不意味着添加观察器对应用程序没有任何影响。
- 内存泄漏。在 Observer 中使用的回调机制(当对象注册为以后调用时)会产生一个常见的错误,从而导致内存泄漏,甚至是在托管的 C# 代码中。假定观察器超出作用范围,但忘记取消对主体的订阅,那么主体仍然保留对观察器的引用。此引用防止垃圾收集在主体对象也被破坏之前重新分配与观察器关联的内存。如果观察器的生存期比主体的生存期短得多(通常是这种情况),则会导致严重的内存泄漏。
- 隐藏的依赖项。观察器的使用将显式依赖性(通过方法调用)转变为隐式依赖性(通过观察器)。如果在整个应用程序中广泛地使用观察器,则开发人员几乎不可能通过查看源代码来了解所发生的事情。这样,就使得了解代码更改的含意非常困难。此问题随传播级别急剧增大(例如,充当 Subject 的观察器)。因此,应该仅在少数定义良好的交互(如 Model-View-Controller 模式中模型和视图之间的交互)中使用观察器。最好不要在域对象之间使用观察器。
- 测试 / 调试困难。尽管松耦合是一项重大的体系结构功能,但是它可以使开发更困难。将两个对象去耦的情况越多,在查看源代码或类的关系图时了解它们之间的依赖性就越难因此,仅当可以安全地忽略两个对象之间的关联时才应该将它们松耦合(例如,如果观察器没有副作用)。
java之设计模式的更多相关文章
- 基于java的设计模式入门(1)——为什么要学习设计模式
大年初一,楼主在这里给大家拜年,祝大家码上升职加薪,码上有对象结婚,码上有车有房,幸福安康. 过完年,回学校注册报道之后,大概就要回深圳到公司开始实习了.提高自己,无非就有两种方式,一是看书学习,二是 ...
- Java 反射 设计模式 动态代理机制详解 [ 转载 ]
Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...
- 单例模式——Java EE设计模式解析与应用
单例模式 目录: 一.何为单例 二.使用Java EE实现单例模式 三.使用场景 一.何为单例 确保一个类只有一个实例,并且提供了实例的一个全局访问点 1.1 单例模式类图 ...
- Java IO设计模式(装饰模式与适配器模式)
01. 装饰模式 1. 定义 Decorator装饰器,就是动态地给一个对象添加一些额外的职责,动态扩展,和下面继承(静态扩展)的比较.因此,装饰器模式具有如下的特征: 它必须持有一个被装饰的对象(作 ...
- java多线程设计模式
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt220 java多线程设计模式 java语言已经内置了多线程支持,所有实现Ru ...
- Java经典设计模式之十一种行为型模式(附实例和详解)
Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:Java经典设计模式之 ...
- Java经典设计模式之七大结构型模式(附实例和详解)
博主在大三的时候有上过设计模式这一门课,但是当时很多都基本没有听懂,重点是也没有细听,因为觉得没什么卵用,硬是要搞那么复杂干嘛.因此设计模式建议工作半年以上的猿友阅读起来才会理解的比较深刻.当然,你没 ...
- Java的设计模式
一.什么是设计模式: 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. ...
- Java EE设计模式(主要简单介绍工厂模式,适配器模式和模板方法模式)
Java EE设计模式分为三种类型,共23种: 创建型模式:单例模式.抽象工厂模式.建造者模式.工厂模式.原型模式. 结构型模式:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式 ...
- JAVA的设计模式之观察者模式----结合ActiveMQ消息队列说明
1----------------------观察者模式------------------------------ 观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的 ...
随机推荐
- 如何获取URL中的参数
获取URL中的某个参数或者所有参数以便我们后续去修改这个地址,在程序中是非常必要的.网上有很多这样的代码片段,为了以后查阅方便,顺便整理思路,下面使用2种方法来获取URL中的某个参数. 方法一 ,sp ...
- 解决Chrome重启后插件被禁用的问题
下载组策略模版,添加白名单 http://pan.baidu.com/s/1o88kcZo 打开组策略 win+r 打开运行,输入 gpedit.msc 添加模版 右键 ->管理模版 -&g ...
- 【开发环境】OFFICE 完全卸载工具(微软)
OFFICE没有正确安装,每次打开OFFICE都会提示: “The setup controller has encountered a problem during instll.Please re ...
- [ImportNew] Perforce - Restoring Mistakenly Deleted Files in Workspace
Shit happens when you accidentally delete some files in your workspace and you have no ideas which o ...
- MongoDB初步(一)
1.软件下载:mongodb-win32-x86_64-2008plus-ssl-3.4.1-signed.msi 2.下载补丁:hotfix kb2731284
- alfresco install in linux, and integrated with tesseract ocr
本文描述在Linux系统上安装Alfresco的步骤: 1. 下载安装文件:alfresco-community-5.0.d-installer-linux-x64.bin 2. 增加执行权限并执行: ...
- 套题 codeforces 361
A题((Mike and Cellphone) 看起来好像需要模拟数字键位的运动,可是,只要判断出那些必然YES的数字组合不就好了么 #include <cstdio> #include ...
- java的 new 关键字
java的new关键字想必大家都知道这是实例化一个对象.没错,也是为新对象分配内存空间. 比如new MyDate(22,7,1964)这样一个案例,他的完成需要四部: 一.为新对象分配内存空间,将M ...
- WIN8 隐私声明
隐私权声明 本应用连接网络仅为控制硬件设备,不会收集你的个人信息,也不共享你个个人信息. 应用名称 CrossMedia可视化控制系统(服务器版) 关于本应用 本应仅为控制设备应用,不关注任何配置相关 ...
- Python学习笔记1——Python基础
一. 数据类型和变量 整数:十六进制用0x前缀和0-9,a-f表示 浮点数:小数,科学计数法:10用e代替:整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的(包括除法),浮点数运算则可 ...