https://www.jianshu.com/p/373316efd293
Builder模式
定义:
指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
类图:
场景:
- 创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。
- 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。
案例:
class Product
{
private String partA;
private String partB;
private String partC;
public void setPartA(String partA)
{
this.partA=partA;
}
public void setPartB(String partB)
{
this.partB=partB;
}
public void setPartC(String partC)
{
this.partC=partC;
}
public void show()
{
//显示产品的特性
}
}
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;
}
}
public class ConcreteBuilder extends Builder
{
public void buildPartA()
{
product.setPartA("建造 PartA");
}
public void buildPartB()
{
product.setPartA("建造 PartB");
}
public void buildPartC()
{
product.setPartA("建造 PartC");
}
}
class Director
{
private Builder builder;
public Director(Builder builder)
{
this.builder=builder;
}
//产品构建与组装方法
public Product construct()
{
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
}
}
public class Client
{
public static void main(String[] args)
{
Builder builder=new ConcreteBuilder();
Director director=new Director(builder);
Product product=director.construct();
product.show();
}
}
工厂模式
定义:
定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。
类图:
场景:
- 客户只知道创建产品的工厂名,而不知道具体的产品名。如 TCL 电视工厂、海信电视工厂等。
- 创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
- 客户不关心创建产品的细节,只关心产品的品牌。
案例:
//抽象产品:提供了产品的接口
interface Product
{
public void show();
}
//具体产品1:实现抽象产品中的抽象方法
class ConcreteProduct1 implements Product
{
public void show()
{
System.out.println("具体产品1显示...");
}
}
//具体产品2:实现抽象产品中的抽象方法
class ConcreteProduct2 implements Product
{
public void show()
{
System.out.println("具体产品2显示...");
}
}
//抽象工厂:提供了厂品的生成方法
interface AbstractFactory
{
public Product newProduct();
}
//具体工厂1:实现了厂品的生成方法
class ConcreteFactory1 implements AbstractFactory
{
public Product newProduct()
{
System.out.println("具体工厂1生成-->具体产品1...");
return new ConcreteProduct1();
}
}
//具体工厂2:实现了厂品的生成方法
class ConcreteFactory2 implements AbstractFactory
{
public Product newProduct()
{
System.out.println("具体工厂2生成-->具体产品2...");
return new ConcreteProduct2();
}
}
public class AbstractFactoryTest
{
public static void main(String[] args)
{
try
{
Product a;
AbstractFactory af;
af=(AbstractFactory) ReadXML1.getObject();
a=af.newProduct();
a.show();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
工厂方法模式VS建造者模式
❑意图不同
在工厂方法模式里,我们关注的是一个产品整体,如超人整体,无须关心产品的各部分是如何创建出来的;但在建造者模式中,一个具体产品的产生是依赖各个部件的产生以及装配顺序,它关注的是“由零件一步一步地组装出产品对象”。简单地说,工厂模式是一个对象创建的粗线条应用,建造者模式则是通过细线条勾勒出一个复杂对象,关注的是产品组成部分的创建过程。❑产品的复杂度不同
工厂方法模式创建的产品一般都是单一性质产品,如成年超人,都是一个摸样,而建造者模式创建的则是一个复合产品,它由各个部件复合而成,部件不同产品对象当然不同。这不是说工厂方法模式创建的对象简单,而是指它们的粒度大小不同。一般来说,工厂方法模式的对象粒度比较粗,建造者模式的产品对象粒度比较细。
两者的区别有了,那在具体的应用中,我们该如何选择呢?是用工厂方法模式来创建对象,还是用建造者模式来创建对象,这完全取决于我们在做系统设计时的意图,如果需要详细关注一个产品部件的生产、安装步骤,则选择建造者,否则选择工厂方法模式。
代理模式
定义:
由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
类图:
场景:
- 远程代理,这种方式通常是为了隐藏目标对象存在于不同地址空间的事实,方便客户端访问。例如,用户申请某些网盘空间时,会在用户的文件系统中建立一个虚拟的硬盘,用户访问虚拟硬盘时实际访问的是网盘空间。
- 虚拟代理,这种方式通常用于要创建的目标对象开销很大时。例如,下载一幅很大的图像需要很长时间,因某种计算比较复杂而短时间无法完成,这时可以先用小比例的虚拟代理替换真实的对象,消除用户对服务器慢的感觉。
- 安全代理,这种方式通常用于控制不同种类客户对真实对象的访问权限。
- 智能指引,主要用于调用目标对象时,代理附加一些额外的处理功能。例如,增加计算真实对象的引用次数的功能,这样当该对象没有被引用时,就可以自动释放它。
- 延迟加载,指为了提高系统的性能,延迟对目标的加载。例如,Hibernate中就存在属性的延迟加载和关联表的延时加载。
案例:
//抽象主题
interface Subject
{
void Request();
}
//真实主题
class RealSubject implements Subject
{
public void Request()
{
System.out.println("访问真实主题方法...");
}
}
//代理
class Proxy implements Subject
{
private RealSubject realSubject;
public void Request()
{
if (realSubject==null)
{
realSubject=new RealSubject();
}
preRequest();
realSubject.Request();
postRequest();
}
public void preRequest()
{
System.out.println("访问真实主题之前的预处理。");
}
public void postRequest()
{
System.out.println("访问真实主题之后的后续处理。");
}
}
public class ProxyTest
{
public static void main(String[] args)
{
Proxy proxy=new Proxy();
proxy.Request();
}
}
装饰者模式
定义:
指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
类图:
场景:
- 当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。
- 当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰模式却很好实现。
- 当对象的功能要求可以动态地添加,也可以再动态地撤销时。
案例:
//抽象构件角色
interface Component
{
public void operation();
}
//具体构件角色
class ConcreteComponent implements Component
{
public ConcreteComponent()
{
System.out.println("创建具体构件角色");
}
public void operation()
{
System.out.println("调用具体构件角色的方法operation()");
}
}
//抽象装饰角色
class Decorator implements Component
{
private Component component;
public Decorator(Component component)
{
this.component=component;
}
public void operation()
{
component.operation();
}
}
//具体装饰角色
class ConcreteDecorator extends Decorator
{
public ConcreteDecorator(Component component)
{
super(component);
}
public void operation()
{
super.operation();
addedFunction();
}
public void addedFunction()
{
System.out.println("为具体构件角色增加额外的功能addedFunction()");
}
}
public class DecoratorPattern
{
public static void main(String[] args)
{
Component p=new ConcreteComponent();
p.operation();
System.out.println("---------------------------------");
Component d=new ConcreteDecorator(p);
d.operation();
}
}
代理模式VS装饰模式
装饰模式就是代理模式的一个特殊应用,两者的共同点是都具有相同的接口,不同点则是代理模式着重对代理过程的控制,而装饰模式则是对类的功能进行加强或减弱,它着重类的功能变化。
- ❑代理模式是把当前的行为或功能委托给其他对象执行,代理类负责接口限定:是否可以调用真实角色,以及是否对发送到真实角色的消息进行变形处理,它不对被主题角色(也就是被代理类)的功能做任何处理,保证原汁原味的调用。代理模式使用到极致开发就是AOP,这是各位采用Spring架构开发必然要使用到的技术,它就是使用了代理和反射的技术。
- ❑装饰模式是在要保证接口不变的情况下加强类的功能,它保证的是被修饰的对象功能比原始对象丰富(当然,也可以减弱),但不做准入条件判断和准入参数过滤,如是否可以执行类的功能,过滤输入参数是否合规等,这不是装饰模式关心的。
组合模式
定义:
有时又叫作部分-整体模式,它是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性。
类图:
场景:
- 在需要表示一个对象整体与部分的层次结构的场合。
- 要求对用户隐藏组合对象与单个对象的不同,用户可以用统一的接口使用组合结构中的所有对象的场合。
案例:
//抽象构件
interface Component
{
public void add(Component c);
public void remove(Component c);
public Component getChild(int i);
public void operation();
}
//树叶构件
class Leaf implements Component
{
private String name;
public Leaf(String name)
{
this.name=name;
}
public void add(Component c){ }
public void remove(Component c){ }
public Component getChild(int i)
{
return null;
}
public void operation()
{
System.out.println("树叶"+name+":被访问!");
}
}
//树枝构件
class Composite implements Component
{
private ArrayList<Component> children=new ArrayList<Component>();
public void add(Component c)
{
children.add(c);
}
public void remove(Component c)
{
children.remove(c);
}
public Component getChild(int i)
{
return children.get(i);
}
public void operation()
{
for(Object obj:children)
{
((Component)obj).operation();
}
}
}
public class CompositePattern
{
public static void main(String[] args)
{
Component c0=new Composite();
Component c1=new Composite();
Component leaf1=new Leaf("1");
Component leaf2=new Leaf("2");
Component leaf3=new Leaf("3");
c0.add(leaf1);
c0.add(c1);
c1.add(leaf2);
c1.add(leaf3);
c0.operation();
}
}
模板方法模式
定义:
定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。
类图:
场景:
- 算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。
- 当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。首先,要识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
- 当需要控制子类的扩展时,模板方法只在特定点调用钩子操作,这样就只允许在这些点进行扩展。
案例:
//抽象类
abstract class AbstractClass
{
public void TemplateMethod() //模板方法
{
SpecificMethod();
abstractMethod1();
abstractMethod2();
}
public void SpecificMethod() //具体方法
{
System.out.println("抽象类中的具体方法被调用...");
}
public abstract void abstractMethod1(); //抽象方法1
public abstract void abstractMethod2(); //抽象方法2
}
//具体子类
class ConcreteClass extends AbstractClass
{
public void abstractMethod1()
{
System.out.println("抽象方法1的实现被调用...");
}
public void abstractMethod2()
{
System.out.println("抽象方法2的实现被调用...");
}
}
public class TemplateMethodPattern
{
public static void main(String[] args)
{
AbstractClass tm=new ConcreteClass();
tm.TemplateMethod();
}
}
网友评论