1 创建型模式
1.1 Builder构建者模式
定义
将⼀个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。它属于创建类模式,⼀般来说,如果⼀个对象的构建⽐较复杂,超出了构造函数所能包含的范围,就可以使⽤⼯⼚模式和Builder模式,相对于⼯⼚模式会产出⼀个完整的产品,Builder应⽤于更加复杂的对象的构建,可以只构建产品的⼀个部分,直⽩来说,就是使⽤多个简单的对象⼀步⼀步构建成⼀个复杂的对象。
例子:使用构建者模式生产电脑
主要步骤:
- 将需要构建的⽬标类分成多个部件(电脑可以分为主机、显示器、键盘、⾳箱等部件)
- 创建构建类
- 依次创建部件
将部件组装成⽬标对象
public class Computer {
private String displayer;
private String mainUnit;
private String mouse;
private String keyboard;
public String getDisplayer() {
return displayer;
}
public void setDisplayer(String displayer) {
this.displayer = displayer;
}
public String getMainUnit() {
return mainUnit;
}
public void setMainUnit(String mainUnit) {
this.mainUnit = mainUnit;
}
public String getMouse() {
return mouse;
}
public void setMouse(String mouse) {
this.mouse = mouse;
}
public String getKeyboard() {
return keyboard;
}
public void setKeyboard(String keyboard) {
this.keyboard = keyboard;
}
@Override
public String toString() {
return "Computer{" + "displayer='" + displayer + '\'' + ", mainUnit='"
+ mainUnit + '\'' + ", mouse='" + mouse + '\'' + ", keyboard='" + keyboard +
'\'' + '}';
}
}
public static class ComputerBuilder {
private ComputerBuilder computer = new ComputerBuilder();
public void installDisplayer(String displayer) {
return computer.setDisplayer(displayer);
}
public void installMainUnit(String mainUnit) {
return computer.setMainUnit(mainUnit);
}
public void installMouse(String mouse) {
return computer.setMouse(mouse);
}
public void installKeybord(String keyboard) {
return computer.setKeyboard(keyboard);
}
public ComputerBuilder build() {
return computer;
}
}
```java public static void main(String[]args){ ComputerBuilder computerBuilder = new ComputerBuilder(); computerBuilder.installDisplayer(“显示器”); computerBuilder.installMainUnit(“主机”); computerBuilder.installKeybord(“键盘”); computerBuilder.installMouse(“⿏标”); Computer computer = computerBuilder.build(); System.out.println(computer); }
<a name="Jk6XP"></a>
## 1.2 工厂模式
<a name="H766B"></a>
### 简单工厂
该模式对对象创建管理方式最为简单,因为其仅仅简单的对不同类对象的创建进行了一层薄薄的封装。该模式通过向工厂传递类型来指定要创建的对象。
<a name="ZrhF6"></a>
#### 例子:
```java
public interface Phone {
void make();
}
public class MiPhone implements Phone {
public MiPhone() {
this.make();
}
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("make xiaomi phone!");
}
}
public class IPhone implements Phone {
public IPhone() {
this.make();
}
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("make iphone!");
}
}
public class PhoneFactory {
public Phone makePhone(String phoneType) {
if(phoneType.equalsIgnoreCase("MiPhone")){
return new MiPhone();
}
else if(phoneType.equalsIgnoreCase("iPhone")) {
return new IPhone();
}
return null;
}
}
工厂方法
和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂
例子:
public interface AbstractFactory {
Phone makePhone();
}
public class XiaoMiFactory implements AbstractFactory{
@Override
public Phone makePhone() {
return new MiPhone();
}
}
public class AppleFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new IPhone();
}
}
抽象工厂方法
例子
public interface PC {
void make();
}
public class MiPC implements PC {
public MiPC() {
this.make();
}
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("make xiaomi PC!");
}
}
public class MAC implements PC {
public MAC() {
this.make();
}
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("make MAC!");
}
}
public interface AbstractFactory {
Phone makePhone();
PC makePC();
}
public class XiaoMiFactory implements AbstractFactory{
@Override
public Phone makePhone() {
return new MiPhone();
}
@Override
public PC makePC() {
return new MiPC();
}
}
public class AppleFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new IPhone();
}
@Override
public PC makePC() {
return new MAC();
}
}
2 结构型模式
2.1 代理模式
以租房为例
首先定义一个租房接口。
public interface IRentingHouse {
void rentHosue();
}
实现租房接口。
public class RentingHouseImpl implements IRentingHouse {
@Override
public void rentHosue() {
System.out.println("我要租用一室一厅的房子");
}
}
静态代理
找中介帮我租房。
public class RentingHouseProxy implements IRentingHouse {
private IRentingHouse rentingHouse;
public RentingHouseProxy(IRentingHouse rentingHouse) {
this.rentingHouse = rentingHouse;
}
@Override
public void rentHosue() {
System.out.println("中介(代理)收取服务费3000元"); // 增强方法
rentingHouse.rentHosue();
System.out.println("客户信息卖了3毛钱"); // 增强方法
}
}
运行。
public static void main(String[] args) {
IRentingHouse rentingHouse = new RentingHouseImpl();
RentingHouseProxy rentingHouseProxy = new RentingHouseProxy(rentingHouse);
rentingHouseProxy.rentHosue();
}
动态代理
1. JDK 动态代理
/**
* Jdk动态代理
* @param obj 委托对象
* @return 代理对象
*/
public Object getJdkProxy(Object obj) {
// 获取代理对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
// 写增强逻辑
System.out.println("中介(代理)收取服务费3000元");
// 调用原有业务逻辑
result = method.invoke(obj,args);
System.out.println("客户信息卖了3毛钱");
return result;
}
});
}
public static void main(String[] args) {
IRentingHouse rentingHouse = new RentingHouseImpl(); // 委托对象---委托方
// 从代理对象工厂获取代理对象
IRentingHouse jdkProxy = (IRentingHouse) ProxyFactory.getInstance().getJdkProxy(rentingHouse);
jdkProxy.rentHosue();
}
2. Cglib动态代理
/**
* 使用cglib动态代理生成代理对象
* @param obj 委托对象
* @return
*/
public Object getCglibProxy(Object obj) {
return Enhancer.create(obj.getClass(), new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Object result = null;
System.out.println("中介(代理)收取服务费3000元");
result = method.invoke(obj,objects);
System.out.println("客户信息卖了3毛钱");
return result;
}
});
}
public static void main(String[] args) {
RentingHouseImpl rentingHouse = new RentingHouseImpl(); // 委托对象
// 获取rentingHouse对象的代理对象,
// Enhancer类似于JDK动态代理中的Proxy
// 通过实现接口MethodInterceptor能够对各个方法进行拦截增强,类似于JDK动态代理中的InvocationHandler
// 使用工厂来获取代理对象
RentingHouseImpl cglibProxy = (RentingHouseImpl) ProxyFactory.getInstance().getCglibProxy(rentingHouse);
cglibProxy.rentHosue();
}