设计模式
设计模式(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包