同步操作将从 dearHaoGeGe/Ebooks 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
抽象工厂简单地说是工厂的工厂,抽象工厂可以创建具体工厂,由具体工厂来产生具体产品。
1)创建共用接口,代码如下:
package com.yoodb;
public interface Dinner{
public void eat();
}
2)创建实现类,代码如下:
package com.yoodb;
public class CatDinner implements Dinner{
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("小猫来吃饭了!");
}
}
package com.yoodb;
public class DogDinner implements Dinner{
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("小狗来吃饭了!");
}
}
3)创建接口,代码如下:
package com.yoodb;
public interface Provider {
public Sender produce();
}
4)创建两个工厂,代码如下:
package com.yoodb;
public class CatFactory implements Provider{
public Dinner produce(){
return new CatDinner();
}
}
package com.yoodb;
public class DogFactory implements Provider{
public Dinner produce(){
return new DogDinner();
}
}
5)main函数测试,代码如下:
package com.yoodb;
public class FactoryTest {
public static void main(String[] args) {
Provider factory = new DogFactory();
Dinner dinner = factory.produce();
dinner.eat();
}
}
1)它对客户屏蔽子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。
2)它实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的。松耦合关系使得子系统的组件变化不会影响到它的客户。Facade模式有助于建立层次结构系统,也有助于对对象之间的依赖关系分层。Facade模式可以消除复杂的循环依赖关系。
这一点在客户程序与子系统是分别实现的时候尤为重要。在大型软件系统中降低编译依赖性至关重要。在子系统类改变时,希望尽量减少重编译工作以节省时间。用Facade可以降低编译依赖性,限制重要系统中较小的变化所需的重编译工作。Facade模式同样也有利于简化系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。
3)如果应用需要,它并不限制它们使用子系统类。因此你可以在系统易用性和通用性之间加以选择。
1、使用时不能用反射模式创建单例,否则会实例化一个新的对象。
2、使用懒单例模式时注意线程安全问题。
3、饿单例模式和懒单例模式构造方法都是私有的,因而是不能被继承的,有些单例模式可以被继承(如登记式模式)。
CGLIB动态代理和jdk代理一样,使用反射完成代理,不同的是他可以直接代理类(jdk动态代理不行,他必须目标业务类必须实现接口),CGLIB动态代理底层使用字节码技术,CGLIB动态代理不能对 final类进行继承。(CGLIB动态代理需要导入jar包)。
CGLIB动态代理原理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
1)接口,具体代码如下:
package com.yoodb.blog;
public interface UserDao {
void save();
}
2)实现业务逻辑类,具体代码如下:
package com.yoodb.blog;
//接口实现类
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("保存数据方法");
}
}
3)代理主要类,具体代码如下:
package com.yoodb.blog;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
private Object targetObject;
// 这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理
public Object getInstance(Object target) {
// 设置需要创建子类的类
this.targetObject = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
//代理实际方法
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("开启事物");
Object result = proxy.invoke(targetObject, args);
System.out.println("关闭事物");
// 返回代理对象
return result;
}
}
4)测试CGLIB动态代理,具体代码如下:
package com.yoodb.blog;
public class Test {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy();
UserDao userDao = (UserDao) cglibProxy.getInstance(new UserDaoImpl());
userDao.save();
}
}
装饰模式优点
1、装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。
2、通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
装饰模式缺点
由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。
解释器模式是类的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。
该模式涉及角色如下:
1)抽象表达式(Expression)角色:声明一个所有的具体表达式角色都需要实现的抽象接口。这个接口主要是一个interpret()方法,称做解释操作。
2)终结符表达式(Terminal Expression)角色:实现了抽象表达式角色所要求的接口,主要是一个interpret()方法;文法中的每一个终结符都有一个具体终结表达式与之相对应。比如有一个简单的公式R=R1+R2,在里面R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。
3)非终结符表达式(Nonterminal Expression)角色:文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,“+"就是非终结符,解析“+”的解释器就是一个非终结符表达式。
4)环境(Context)角色:这个角色的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,我们给R1赋值100,给R2赋值200。这些信息需要存放到环境角色中,很多情况下我们使用Map来充当环境角色就足够了。
Java中实现解释器模式,说一说演示代码。
1、实体类Context,具体代码如下:
package com.yoodb;
public class Context {
private Integer numo;
private Integer numt;
public Context(Integer numo, Integer numt) {
this.numo = numo;
this.numt = numt;
}
public Integer getNumo() {
return numo;
}
public void setNumo(Integer numo) {
this.numo = numo;
}
public Integer getNumt() {
return numt;
}
public void setNumt(Integer numt) {
this.numt = numt;
}
}
2、一个接口,具体代码如下:
package com.yoodb;
public interface Expression {
public int interpret(Context context);
}
3、两个接口实现类,一个类是参数相加,一个类是参数相减,具体代码如下:
package com.yoodb;
public class Minus implements Expression {
@Override
public int interpret(Context context) {
// TODO Auto-generated method stub
return context.getNumo()-context.getNumt();
}
}
package com.yoodb;
public class Plus implements Expression {
@Override
public int interpret(Context context) {
// TODO Auto-generated method stub
return context.getNumo() + context.getNumt();
}
}
4、单元测试,具体代码如下:
package com.yoodb;
public class MainTest {
public static void main(String[] args) {
int result = new Minus().interpret((new Context(new Plus().interpret(new Context(2015, 8)), 4)));
System.out.println(result);
}
}
运行结果如下:
2019
Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:
1)Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组;这个抽象方法在代理类中动态实现。
2)Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容:
Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。
Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。
Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。
接口(或抽象类),具体代码如下:
package com.yoodb;
public interface Business {
public void doAction();
}
此处是真正意义上实现业务逻辑的类,具体代码如下:
package com.yoodb;
public class BusinessImpl implements Business {
@Override
public void doAction() {
// TODO Auto-generated method stub
System.out.println("实现业务逻辑.");
}
}
动态代理方式,具体代码如下:
package com.yoodb;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicBusinessProxy implements InvocationHandler{
private Object obj;
public DynamicBusinessProxy() {}
public DynamicBusinessProxy(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
Object result = null;
doBefore();
result = method.invoke(obj, args);
doAfter();
return result;
}
private void doBefore(){
System.out.println("调用目标对象前做相关操作");
}
private void doAfter(){
System.out.println("调用目标对象后做相关操作");
}
public static Object factory(Object obj)
{
Class<? extends Object> cls = obj.getClass();
return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),new DynamicBusinessProxy(obj));
}
}
单元测试,具体代码如下:
package com.yoodb;
public class MainTest {
public static void main(String[] args) {
Business business = (Business) DynamicBusinessProxy.factory(new BusinessImpl());
business.doAction();
}
}
运行之后结果如下:
调用目标对象前做相关操作
实现业务逻辑.
调用目标对象后做相关操作
原型模式是一种创建型设计模式,通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。
原型设计模式简单来说就是克隆,原型模式多用于创建复杂的或者构造耗时的实例,因为这种情况下,复制一个已经存在的实例可使程序运行更高效。
原型模式有两种表现形式:
1)简单形式;
2)登记形式,这两种表现形式仅仅是原型模式的不同实现。
简单形式的原型模式,涉及到三种角色分别如下:
1)客户(Client)角色:客户类提出创建对象的请求。
2)抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。
3)具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
public class Singleton {
private static boolean flag = false;
private Singleton() {
if (flag == false) {
flag = !flag;
} else {
throw new RuntimeException("关注Java精选公众号,提醒单例模式被攻击!");
}
}
public static void main(String[] args) {
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。