建造者模式 Builder
定义
- 建造者模式是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
- 它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
- 建造者(Builder)模式的角色:
- 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个滅部件。
- 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
- 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
-
指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
在这里插入图片描述
以制造自行车为例,自行车由车架、轮胎、脚踏等部件组成,自行车制造公司就是把这些零部件组装起来。
自行车制造公司的工程部门相当于指挥者,生产部门相当于建造者,当今共享单车做的比较大的摩拜和ofo相当于客户,单车就是产品了。结构图如下所示:
在这里插入图片描述
实现
package io.ilss.pattern.builder;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
/**
* @author : feng
* @description: Product
* @date : 2019-04-23 15:14
* @version: : 1.0
*/
@Setter
@Slf4j
@ToString
class Product {
private String partA;
private String partB;
private String partC;
public void show() {
log.info(toString());
}
}
package io.ilss.pattern.builder;
/**
* @author : feng
* @description: Builder 抽象产品建造者
* @date : 2019-04-23 15:19
* @version: : 1.0
*/
public abstract class Builder {
//创建产品对象
protected Product product = new Product();
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
//返回产品对象
public Product getResult() {
return product;
}
}
package io.ilss.pattern.builder;
/**
* @author : feng
* @description: ConcreteOneBuilder 具体的建造者
* @date : 2019-04-23 15:20
* @version: : 1.0
*/
public class ConcreteOneBuilder extends Builder {
@Override
public void buildPartA() {
product.setPartA("PartA-1");
}
@Override
public void buildPartB() {
product.setPartB("PartB-1");
}
@Override
public void buildPartC() {
product.setPartC("PartC-1");
}
}
package io.ilss.pattern.builder;
/**
* @author : feng
* @description: ConcreteTwoBuilder
* @date : 2019-04-23 15:22
* @version: : 1.0
*/
public class ConcreteTwoBuilder extends Builder{
@Override
public void buildPartA() {
product.setPartA("PartA-2");
}
@Override
public void buildPartB() {
product.setPartB("PartB-2");
}
@Override
public void buildPartC() {
product.setPartC("PartC-2");
}
}
package io.ilss.pattern.builder;
/**
* @author : feng
* @description: Director
* @date : 2019-04-23 15:21
* @version: : 1.0
*/
public class Director {
private Builder builder;
public Director(Builder builder)
{
this.builder=builder;
}
//产品构建与组装方法
public Product construct()
{
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
}
}
代理模式 Proxy
定义
-
由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
-
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是生活中常见的中介。
-
代理模式包含一下三个角色:
- 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
- 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
-
代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
在这里插入图片描述
实现
- 代理模式实现
package io.ilss.pattern.proxy;
/**
* @author : feng
* @description: Subject 抽象主题
* @date : 2019-04-24 09:16
* @version: : 1.0
*/
public interface Subject {
void request();
}
package io.ilss.pattern.proxy;
import lombok.extern.slf4j.Slf4j;
/**
* @author : feng
* @description: RealSubject 真实主题
* @date : 2019-04-24 09:17
* @version: : 1.0
*/
@Slf4j
public class RealSubject implements Subject {
@Override
public void request() {
log.info("访问真实主题方法...");
}
}
package io.ilss.pattern.proxy;
import lombok.extern.slf4j.Slf4j;
/**
* @author : feng
* @description: Proxy 代理
* @date : 2019-04-24 09:16
* @version: : 1.0
*/
@Slf4j
class Proxy implements Subject {
private Subject subject;
@Override
public void request() {
if (subject == null) {
subject = new RealSubject();
}
log.info("访问真实主题之前的预处理。");
subject.request();
log.info("访问真实主题之后的后续处理。");
}
}
package io.ilss.pattern.proxy;
/**
* @author : feng
* @description: ProxyTest
* @date : 2019-04-24 09:19
* @version: : 1.0
*/
public class ProxyTest {
public static void main(String[] args) {
Proxy proxy=new Proxy();
proxy.request();
}
}
- jdk动态代理简单实现
package io.ilss.pattern.proxy.jdk;
/**
* @author : feng
* @description: Work
* @date : 2019-04-24 09:22
* @version: : 1.0
*/
public interface Work {
void todo();
}
package io.ilss.pattern.proxy.jdk;
import lombok.extern.slf4j.Slf4j;
/**
* @author : feng
* @description: Work
* @date : 2019-04-24 09:23
* @version: : 1.0
*/
@Slf4j
public class WorkImpl implements Work {
@Override
public void todo() {
log.info("do some work jdk!");
}
}
package io.ilss.pattern.proxy.jdk;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author : feng
* @description: JdkProxy
* @date : 2019-04-24 09:26
* @version: : 1.0
*/
@Slf4j
public class JdkProxy implements InvocationHandler {
private Object object;
public JdkProxy(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log.info("开始预处理");
object = method.invoke(object, args);
log.info("结结束时处理");
return object;
}
public Object getInstance() {
return Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), new Class[]{Work.class}, this);
}
}
package io.ilss.pattern.proxy.jdk;
import java.lang.reflect.Proxy;
/**
* @author : feng
* @description: ProxyTest
* @date : 2019-04-24 09:33
* @version: : 1.0
*/
public class ProxyTest {
public static void main(String[] args) {
JdkProxy proxy = new JdkProxy(new WorkImpl());
Work work = (Work) proxy.getInstance();
work.todo();
}
}
- cglib 动态代理简单实现
package io.ilss.pattern.proxy.cglib;
import lombok.extern.slf4j.Slf4j;
/**
* @author : feng
* @description: Work
* @date : 2019-04-24 09:23
* @version: : 1.0
*/
@Slf4j
public class Work {
public void todo() {
log.info("do some work cglib!");
}
}
package io.ilss.pattern.proxy.cglib;
import lombok.extern.slf4j.Slf4j;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @author : feng
* @description: CglibProxy
* @date : 2019-04-25 10:17
* @version: : 1.0
*/
@Slf4j
public class CglibProxy implements MethodInterceptor {
private Object object;
public CglibProxy(Object object) {
this.object = object;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
log.info("开始预处理");
object = methodProxy.invokeSuper(o, objects);
log.info("结结束时处理");
return object;
}
public Object getInstance() {
//创建加强器,用来创建动态代理类
Enhancer enhancer = new Enhancer();
//为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)
enhancer.setSuperclass(this.object.getClass());
//设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦
enhancer.setCallback(this);
// 创建动态代理类对象并返回
return enhancer.create();
}
}
package io.ilss.pattern.proxy.cglib;
/**
* @author : feng
* @description: ProxyTest
* @date : 2019-04-24 09:33
* @version: : 1.0
*/
public class ProxyTest {
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy(new Work());
Work work = (Work) proxy.getInstance();
work.todo();
}
}
适配器模式 Adapter
定义
将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作
-
类适配器
在这里插入图片描述 -
对象适配器
在这里插入图片描述
适配器模式包含一下三个角色:
- Target(目标抽象类):目标抽象类定义客户所需的接口,可以是一个抽象类或接口,也可以是具体类。在类适配器中,由于C#语言不支持多重继承,所以它只能是接口。
- Adapter(适配器类):它可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配。它是适配器模式的核心。
- Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类包好了客户希望的业务方法。
实现
package io.ilss.pattern.adapter;
/**
* @author : feng
* @description: Target 目标接口
* @date : 2019-04-25 14:26
* @version: : 1.0
*/
interface Target {
public void request();
}
package io.ilss.pattern.adapter;
import lombok.extern.slf4j.Slf4j;
/**
* @author : feng
* @description: Adaptee 适配者接口
* @date : 2019-04-25 14:27
* @version: : 1.0
*/
@Slf4j
public class Adaptee {
public void specificRequest() {
log.info("适配者中的业务代码被调用!");
}
}
- 类适配器
package io.ilss.pattern.adapter;
/**
* @author : feng
* @description: ClassAdapter 类适配器类
* @date : 2019-04-25 14:27
* @version: : 1.0
*/
public class ClassAdapter extends Adaptee implements Target {
@Override
public void request() {
specificRequest();
}
}
- 对象适配器
package io.ilss.pattern.adapter;
/**
* @author : feng
* @description: ObjectAdapter 对象适配器
* @date : 2019-04-25 14:28
* @version: : 1.0
*/
public class ObjectAdapter implements Target {
private Adaptee adaptee;
public ObjectAdapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest();
}
}
package io.ilss.pattern.adapter;
import lombok.extern.slf4j.Slf4j;
/**
* @author : feng
* @description: AdapterTest
* @date : 2019-04-25 14:29
* @version: : 1.0
*/
@Slf4j
public class AdapterTest {
public static void main(String[] args) {
log.info("类适配器模式:");
Target target1 = new ClassAdapter();
target1.request();
log.info("对象适配器模式测试:");
Adaptee adaptee = new Adaptee();
Target target2 = new ObjectAdapter(adaptee);
target2.request();
}
}
桥接模式 Bridge
定义
- Bridge 模式是构造型的设计模式之一。Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展。
- Bridge将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
- 桥接(Bridge)模式包含以下主要角色。
- 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
- 扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现3. 父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
- 实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
-
具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。
在这里插入图片描述
实现
package io.ilss.pattern.bridge;
/**
* @author : feng
* @description: Implementor 实现化角色
* @date : 2019-04-26 16:00
* @version: : 1.0
*/
public interface Implementor {
void operationImpl();
}
package io.ilss.pattern.bridge;
import lombok.extern.slf4j.Slf4j;
/**
* @author : feng
* @description: ConcreteImplementorA
* @date : 2019-04-26 16:01
* @version: : 1.0
*/
@Slf4j
public class ConcreteImplementorA implements Implementor {
@Override
public void operationImpl() {
log.info("具体实现化(Concrete Implementor)角色被访问 ConcreteImplementorB!!!");
}
}
package io.ilss.pattern.bridge;
import lombok.extern.slf4j.Slf4j;
/**
* @author : feng
* @description: ConcreteImplementorB
* @date : 2019-04-26 16:08
* @version: : 1.0
*/
@Slf4j
public class ConcreteImplementorB implements Implementor {
@Override
public void operationImpl() {
log.info("具体实现化(Concrete Implementor)角色被访问 ConcreteImplementorB!!!");
}
}
package io.ilss.pattern.bridge;
/**
* @author : feng
* @description: Abstraction
* @date : 2019-04-26 16:03
* @version: : 1.0
*/
public abstract class Abstraction {
protected Implementor implementor;
protected Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
package io.ilss.pattern.bridge;
import lombok.extern.slf4j.Slf4j;
/**
* @author : feng
* @description: RefineAbstraction
* @date : 2019-04-26 16:04
* @version: : 1.0
*/
@Slf4j
public class RefinedAbstraction extends Abstraction {
protected RefinedAbstraction(Implementor implementor) {
super(implementor);
}
@Override
public void operation() {
log.info("扩展抽象化(Refined Abstraction)角色被访问");
implementor.operationImpl();
}
}
参考文章
- http://c.biancheng.net/view/1354.html
- https://www.cnblogs.com/jenkinschan/p/6426694.html
- https://baike.baidu.com/item/代理模式/8374046
- http://c.biancheng.net/view/1359.html
- http://c.biancheng.net/view/1361.html
- http://c.biancheng.net/view/1364.html
- https://baike.baidu.com/item/桥接模式
- https://baike.baidu.com/item/适配器模式
- https://www.cnblogs.com/cenyu/p/6289209.html
- http://www.cnblogs.com/ygj0930/p/6542259.html
- https://www.cnblogs.com/songyaqi/p/4805820.html
网友评论