设计模式(工厂模式和代理模式)

设计模式

设计模式(Design Pattern)是人们在长期的软件开发应用中对一些经验的总结,是对某些特定问题经过时间检验的特定解决方法。

设计模式使人们可以更加简单方便地复用成功的设计和体系结构。将已正式的技术方案总结成设计模式,也会使其他开发者更加容易理解其设计思路。
目前所说的设计模式通常始终GoF实际模式。GoF(Gang of Four,四人组)指的是Design Patterns;Elements of Reusable Object-Oriented Software 这本书的4位作者:Gamma、Helm、Johnson和Vlissides书中总结了23中经典的设计模式,因此也被称为GoF设计模式
分类方式:
1.根据目的划分,既根据设计模式是用于完成何种工作来划。分为:
A.创建型模式:用于描述“如何创建对象”,主要特点是“将对象的创建与使用分离”。
B.结构型模式:用于描述如何将类或对象按某种布局组成更大的结构。
C.行为型模式:用于描述类或对象之间如何相互协作,共同完成单个对象无法独立完成的任务,以及如何分配职责。
2.根据作用范围划分,级根据设计模式主要作用于类上还是主要用于对象上来划分。分为:
A.类模式:用于处理类与子类之间的关系,这些关系通过继承来建立,是静态的,在编译时刻便确定下来。
B.对象模式:用于处理对象之间的关系,这些关系可以通过组合或聚合来实现,在运行时是可以变化的,更具动态性。
面向对象设计原则:
面向对象的软件设计提出了几大原则。这些原则可以用来检验软件系统设计的合理性,也被设计模式所遵循。
分为:
1.单一职责原则(一个类做一件事)
该原则提出一个类不应该承担太多职责。如果一个类承担了太多的职责,至少存在以下两个缺点:
(1). 一个职责的变化可能影响这个类实现其他职责的能力,或者引发其他职责故障。
(2)当客户需要该类的某一个职责时,不得不将其他不需要的职责全部包含进来,从而造成冗余或风险。
2.开闭原则(对扩展开放,对修改关闭)
开闭原则是面向对象设计中最基础的设计原则,开闭原则规定一个软件实体,如类、模块和函数应该对扩展开放,对修改关闭。这就需要使用接口,面向接口编程
3.里氏替换原则(对使用父类的地方,一定能使用子类)
4.依赖倒置原则
依赖倒置原则的核心思想是:依赖于约定而不依赖于具体实现,即面向接口编程。对象的依赖关系有3种传递方式。
(1)通过构造方法传递依赖对象,即构造方法的参数是需要依赖的接口类型。
(2)通过setter方法传递依赖队形,即setter方法的参数是需要依赖的接口类型。
(3)接口声明依赖,即接口方法的参数是需要依赖的接口类型。
Ps:如果开闭原则是面向对象设计的目标,那么依赖倒置原则就是实现开闭原则的重要途径之一,它降低了客户与实现模块之间的耦合。
5.接口隔离原则(接口的单一、精简)
接口隔离原则要求尽量将庞大臃肿的接口拆分成更小、更具体的接口,让接口中只包含客户感兴趣的方法。
接口隔离原则和单一职责原则都是为了提高类的内聚性,降级它们之间的耦合度,但两者是不同的。
(1)单一职责原则注重的是职责,而接口隔离原则注重的是对接口依赖的隔离。
(2)单一职责原则主要是约束类,它针对的事程序中的实现和细节;而接口隔离原则主要约束接口主要针对抽象和程序整体框架的构建。
6.迪米特法则(最少知道原则)
是指一个软件实体应当尽可能少的与其他实体发生相互作用,具体来讲,被依赖的类应尽量将复杂逻辑封装在类的内部;不对外泄露任何中间信息,是客户对中中间过程中的其他实体保持最少的了解,从而减少不必要的依赖,降低耦合。
7.合成复用原则
合成复用原则是指:尽量使用组合/聚合的方式,而不是继承关系达到软件复用的目的。

工厂设计模式

分为:
1.简单工厂模式
2.抽象工厂模式
3.工厂方法模式

public interface JDBC {
	/**
	 * 返回JDBC管理对象
	 */
	public void getManager();
}
public class MySQLJDBC implements JDBC {

	@Override
	public void getManager() {
		System.out.println("MySQL JDBC!");
	}
}
public class OracleJDBC implements JDBC {

	@Override
	public void getManager() {
		System.out.println("Oracle JDBC!");
	}
}
public class SQLServerJDBC implements JDBC {

	@Override
	public void getManager() {
		System.out.println("SQL Server JDBC!");
	}
}
public interface JDBCFactory {
	public  JDBC getJDBC();
}
public class MySQLJDBCFactory implements JDBCFactory{
	@Override
	public JDBC getJDBC() {
		return new MySQLJDBC();
	}
}
public class OracleJDBCFactory implements JDBCFactory{
	@Override
	public JDBC getJDBC() {
		return new OracleJDBC();
	}
}
public class SQLServerJDBCFactory implements JDBCFactory{
	@Override
	public JDBC getJDBC() {
		return new SQLServerJDBC();
	}
}
public class NewOperating {

	private JDBC jdbc;

	public void setJdbc(JDBC jdbc) {
		this.jdbc = jdbc;
	}

	public void use() {
		jdbc.getManager();
	}
	
	public static void main(String[] args) {
		NewOperating operating=new NewOperating();
		
		//工厂类对象
		JDBCFactory factory=new OracleJDBCFactory();
	    //JDBCFactory factory=new MySQLJDBCFactory();//创建工厂对象

		JDBC jdbc=factory.getJDBC();//获得具体产品
		//传入具体产品
		operating.setJdbc(jdbc);// setter方法
		
		operating.use();
	}
}

代理模式

分为:
静态代理和动态代理

静态代理
public interface Buyer {
    /**
     * 查看房屋
     * @return 反馈
     */
    public String havealook();
}
public class RealBuyer implements Buyer {
    @Override
    public String havealook() {
        System.out.println("*****买家实地查看一下");
        return "------买家提出一些意见";
    }
}
public class Intermediary implements Buyer {
    /**
     * 被代理的目标对象
     */
    private Buyer target;

    public Intermediary(Buyer target) {
        this.target = target;
    }

    /**
     * 对目标对象业务进行代理
     */
    @Override
    public String havealook() {
        before();
        String feedback = target.havealook(); // 执行目标对象的实际业务
        after();
        return "最后中介和买家沟通>>>>>>>>>>>>>>>>>>看房记录:买家反馈" + feedback ;
    }

    public void before() {
        System.out.println("============中介前期准备。");
        System.out.println("============中介查找房源。");
        System.out.println("============中介和卖家沟通时间。");
    }
    public void after() {
        System.out.println("$$$$$$$$$$$$中介后期跟踪");
        System.out.println("$$$$$$$$$$$$中介和买家沟通意见。");
    }
}
public class BuyerTest {
	public static void main(String[] args) throws Exception {
		RealBuyer user=new RealBuyer();//创建真实用户
        Buyer buyer = new Intermediary(user);//创建代理对象[中介],将被代理者交给中介 管理
        String result = buyer.havealook();
        System.out.println(result);
    }
}
动态代理

又分为JDK代理和cglib代理
JDK代理

public class Movie {
	/**
	 * 万达售票: 根据VIP级别排队购买电影票
	 * @param vip
	 * @param ticketName
	 * @return
	 */
	public static String payTicket(int vip,String ticketName){
		try {
			if (vip==0) {
				Thread.sleep(5000);
			}else if (vip==1) {
				Thread.sleep(4000);
			}else if (vip==2) {
				Thread.sleep(2000);
			}else if (vip==3) {
				
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
		return ticketName+" 购买成功!";
	}
}

public interface User {
	/**
	 * 购买电影票
	 * @return
	 */
	public String buyTicket();
}

public class RealUser implements User{
	public String buyTicket() {
		System.out.println("排队中....");
		return "电影票: 火影忍者";
	}
	/**
	 * 0级 VIP
	 * @return
	 */
	public int getVIP() {
		return 0;
	}
}

/**
 * 调用 处理程序: 相当于一个代理对象.
 * @author Administrator
 */
public class IntermediaryInvocationHandler implements InvocationHandler {
    /**
     * 被代理的目标对象
     */
	private Object target;
	public void setTarget(Object target) {
        this.target = target;
    }
    /**
     * 为被代理的接口方法定义的代理业务规则
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
    	//Method对象.invoke(对象实例,参数): 反射方式,执行被代理对象的指定方法
        String ticketName = (String) method.invoke(target, args);
        String result= Movie.payTicket(getVIP(), ticketName);
        return result;
    }
    /**
	 * 10级 VIP
	 * @return
	 */
	public int getVIP() {
		return 10;
	}
}

public class TicketTest {
    public static void main(String[] args) throws Exception {
    	//创建真实对象
        Object target=new RealUser();
        //创建 处理程序
        IntermediaryInvocationHandler handler = new IntermediaryInvocationHandler();
        //设置 处理程序操作的真实对象
        handler.setTarget(target);
        //获得代理对象: 根据指出的接口和真实类,以实现接口的方式为真实类创建代理对象.
        //Proxy类
        User user =(User) Proxy.newProxyInstance(target.getClass().getClassLoader(),
        		target.getClass().getInterfaces(), handler);
        //当使用代理对象访问方法时,会将方法调用指派给"处理程序[Handler]". 处理程序会执行invoke()
        String result = user.buyTicket();
        System.out.println(result);
    }

}

cglib代理

public class RealBuyer {
    private Logger logger = Logger.getLogger(RealBuyer.class);

    public String havealook() {
        logger.debug("---->>>>>>>实地查看一下");
        return "---->>>>>>>一些意见";
    }
}

public class IntermediaryCglibProxyFactory {

    //MethodInterceptor接口 实现类 拦截器
    private static IntermediaryMethodInterceptor callback = new IntermediaryMethodInterceptor();

    /**
     * 工厂方法
     * @param target 需要被代理的类型,即代理类需要继承的父类型
     * @return 代理类的实例
     */
    public static <T> T create(Class<T> target) {
        //增强器
        //Enhancer负责动态生成代理 = 目标对象的子类
        Enhancer enhancer = new Enhancer();
        enhancer.setCallback(callback); // 为重写的方法指定回调的MethodInterceptor
        enhancer.setSuperclass(target); // 指定要继承的父类型,即需要被代理的类型
        return (T) enhancer.create(); // 动态生成子类,创建子类实例并返回
    }
}

public class IntermediaryMethodInterceptor implements MethodInterceptor {
    private Logger logger = Logger.getLogger(IntermediaryMethodInterceptor.class);
    /**
     * 为被代理的方法定义的代理业务规则
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)
            throws Throwable {
        before();
        Object feedback = methodProxy.invokeSuper(proxy, args); // 调用父类原始的方法
        after();
        return "最后中介和买家沟通>>>>>>>>>>>>>>>>>>看房记录:买家反馈" + feedback;
    }

    public void before() {
        logger.debug("============中介前期准备");
        logger.debug("============中介查找房源");
        logger.debug("============中介和卖家沟通时间。");
    }

    public void after() {
        logger.debug("$$$$$$$$$$$$中介后期跟踪");
        logger.debug("$$$$$$$$$$$$中介和买家沟通意见。");
    }
}

public class BuyerTest {
    private final Logger logger = Logger.getLogger(BuyerTest.class);

    @Test
    public void havealookCglibProxy() throws Exception {
        RealBuyer buyer = IntermediaryCglibProxyFactory.create(RealBuyer.class);
        String result = buyer.havealook();
        logger.debug(result);
    }

}

**ps:**在使用上述方法中要使用cglib-nodep-3.3.0.jar和log4j-1.2.17.jar两个jar包

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值