1、工厂方法模式(Factory Method)
1.1 带参数工厂方法模式->定义一个接口并提供一个方法, 多个具体类来实现这个接口. 创建一个工厂类并提供一个带参数的方法, 此方法根据参数值来创建具体类对象实例.
public interface Driver{
void connect();
}
public class OracleDriver implements Driver{
public void connect(){
System.out.println("implement oracle driver");
}
public class SybaseDriver implements Driver{
public void connect(){
System.out.println("implement sybase driver");
}
public class DriverFactory{
public Driver produce(String driverType){
if ("oracle".equals(driverType)){
return new OracleDriver();
}else if ("sybase".equals(driverType)){
return new SybaseDriver();
}else{
return null
}
}
}
public class TestDriver{
public static void main(String args[]){
DriverFactory factory = new DriverFactory();
OracleDriver oracle = factory.produce("oracle");
SybaseDriver sybase = factory.produce("sybase");
}
}
1.2. 多个工厂方法模式( factory method) -> 定义一个接口并提供一个方法, 多个具体类来实现这个接口. 创建一个工厂类并提供每个具体类的方法来创建具体类对象实例.
public interface Driver{
void connect();
}
public class OracleDriver implements Driver{
public void connect(){
System.out.println("implement oracle driver");
}
public class SybaseDriver implements Driver{
public void connect(){
System.out.println("implement sybase driver");
}
}
public class DriverFactory{
public Driver produceOracle(){
return new OracleDriver();
} public Driver produceSybase{){
return new SybaseDriver();
}}
public class TestDriver{
public static void main(String args[]){
DriverFactory factory = new DriverFactory();
OracleDriver oracle = factory.produceOracle;
SybaseDriver sybase = factory.produceSybase;
}
}
1.3 静态工厂方法模式,将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。
2. 抽象工厂模式(Abstract Factory)
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了开放--关闭原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码
public interface Driver{
void connect();
}
public class OracleDriver implements Driver{
public void connect(){
System.out.println("implement oracle driver");
}
public class SybaseDriver implements Driver{
public void connect(){
System.out.println("implement sybase driver");
}
public interface Provider{
void Driver produce();
}
public class OracleDriverFactory implements Provider{
public Driver produce(){
return new OracleDriver();
}}
public class SybaseDriverFactory implements Provider{
public Driver produce(){
return new SybaseDriver();
}}
public class TestDriver{
public static void main(String args[]){
Provider oracleProvider = new OracleDriverFactory();
OracleDriver oracle = oracleProvider.product();
Provider sybaseProvider = new SybaseDriverFactory();
SybaseDriver sybase= sybaseProvider.product();
}
3、单例模式(Singleton)
单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处:
1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。
2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。
3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。public class Singleton{
private static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance
}
}
4、建造者模式(Builder)
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 [构建与表示分离,同构建不同表示]
与抽象工厂的区别:在建造者模式里,有个指导者,由指导者来管理建造者,用户是与指导者联系的,指导者联系建造者最后得到产品。即建造模式可以强制实行一种分步骤进行的建造过程。
建造模式是将复杂的内部创建封装在内部,对于外部调用的人来说,只需要传入建造者和建造工具,对于内部是如何建造成成品的,调用者无需关心。
举个简单的例子,如汽车,有很多部件,车轮,方向盘,发动机还有各种小零件等等,部件很多,但远不止这些,如何将这些部件装配成一部汽车,这个装配过程也很复杂(需要很好的组装技术), builder模式就是为了将部件和组装分开。
public interface Builder{
void buildPartA();
void buildPartB();
void buildPartC();
Product getResult();
}
public interface Part{}
public intterface Product{}
public class ConcreteBuilder implements Builder {
Part partA, partB, partC;
public void buildPartA() {
//这里是具体如何构建partA的代码
};
public void buildPartB() {
//这里是具体如何构建partB的代码
};
public void buildPartC() {
//这里是具体如何构建partB的代码
};
public Product getResult() {
//返回最后组装成品结果
};
}
public class Director{
private Builder builder
public Director(Builder builer){
this.builder = builder;
}
public void construct(){
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
}
}
public class Test{
public static void main(Stirng args[]){
ConcreteBuilder builder = new ConcreteBuilder();
Director director = new Director( builder );
director.construct();
Product product = builder.getResult();
}
}
5、原型模式(Prototype)
原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象public abstract class AbstractSpoon implements Cloneable{
String spoonName;
public void setSpoonName(String spoonName) {this.spoonName = spoonName;}
public String getSpoonName() {return this.spoonName;}
public Object clone(){
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException exception) {
System.err.println("AbstractSpoon is not Cloneable");
}
return object;
}
}
public class SoupSpoon extends AbstractSpoon{
public SoupSpoon(){
setSpoonName("Soup Spoon");
}
}
public class Test{
public static void main(Stirng args[]){
AbstractSpoon spoon = new SoupSpoon();
AbstractSpoon spoon2 = spoon.clone();
}
}
6、适配器模式(Adapter)
适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题
6.1 类适配器模式-〉适配类继承一个待适配的具体类并实现一个接口
public class OracleDriver{
public void connectOracle(){
System.out.println("connect to oracle ");
}
}
public interface Driver {
void connectOracle();
void connectSybase();
}
public class Adapter extend OracleDriver implements Driver{
public void connectSybase(){
System.out.println("connect to sybase");
}
}
public class Test{
public static void main(Stirng args[]){
Driver adapter= new Adapter();
adapter.connectOracle();
adapter.connectSybase();
}
}
6.2 对象的适配器模式 ->适配类实现一个接口并持有待适配的具体类的实例,通过构造函数传入待适配对象实例
public class OracleDriver{
public void connectOracle(){
System.out.println("connect to oracle ");
}
}
public interface Driver {
void connectOracle();
void connectSybase();
}
public class Adapter implements Driver{
private OracleDriver oracle;
publuc Adapter(OracleDriver oracle){
this.oracle = oracle;
}
public void connectOracle(){
this.oracle.connectOracle();
}
public void connectSybase(){
System.out.println("connect to sybase");
}
}
public class Test{
public static void main(Stirng args[]){
Driver adapter= new Adapter(new OracleDriver());
adapter.connectOracle();
adapter.connectSybase();
}
}
6.3 接口的适配器模式
有时我们写的一个接口中有多个抽象方法,当我们写该接口的实现类时,必须实现该接口的所有方法,这明显有时比较浪费,因为并不是所有的方法都是我们需要的,有时只需要某一些,此处为了解决这个问题,我们引入了接口的适配器模式,借助于一个抽象类,该抽象类实现了该接口所有的方法,而我们不和原始的接口打交道,只和该抽象类取得联系,所以我们写一个类,继承该抽象类,重写我们需要的方法就行。
public interface Driver {
void connectOracle();
void connectSybase();
}
public abstract class abstractDriver implemnets Driver{ //did nothing
public void connectOracle(){}
public void connectSybase(){}
}
public class OracleDriver extend abstractDriver{
public void connectOracle(){
System.out.println("connect to oracle ");
}
}
public class SybaseDriver extend abstractDriver{
public void connectSybase(){
System.out.println("connect to syabae");
}
public class Test{
public static void main(Stirng args[]){
Driver oracle= new OracleDriver();
oracle.connectOracle();
Driver sybase= new SybaseDriver();
sybase.connectSybase();
}
}
7、装饰模式(Decorator)
装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例, 装饰对象通过构造函数传入被装饰对象。
public interface Driver{
void connect();
}
public class OracleDriver implements Driver{
public void connect(){
System.out.println("connect to oracle");
}
}
public class Decorator implements Driver{
private OracleDriver oracle;
public Decorator(OracleDriver oracle){
this.oracle = oracle;
}
public void connect(){
System.out.println("check parameter")
if (true){
oracle.connect();
}
System.out.println("connected to oracle successfully");
}
}
public class Test{
public static void main(String args[]){
Driver oracle = new OracleDriver();
Driver decorator = new Decorator(oracle);
decorator.connect();
}
}
8、代理模式(Proxy)
代理模式就是多一个代理类出来,替原对象进行一些操作,比如我们在租房子的时候回去找中介,为什么呢?因为你对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人去帮你做,此处的代理就是这个意思。再如我们有的时候打官司,我们需要请律师,因为律师在法律方面有专长,可以替我们进行操作,表达我们的想法。
代理类和被代理类实现同一个接口,代理类持有被代理类对象实例并同过构造函数new一过个被代理类对象实例。
public interface Driver{
void connect();
}
public class OracleDriver implements Driver{
public void connect(){
System.out.println("connect to oracle");
}
}
public class Proxy implements Driver{
private OracleDriver oracle;
public Decorator(){
this.oracle = new OracleDriver();
}
public void connect(){
before();
oracle.connect();
after();
private void before(){
System.out.println("do some initial things");
}
private void after(){
System.out.println("do some subsequent things");
}}
public class Test{
public static void main(String args[]){
Driver oracle = new OracleDriver();
Driver proxy= new Proxy();
proxy.connect();
}
}
9、外观模式(Facade)
外观模式是为了解决类与类之家的依赖关系的,像spring一样,可以将类和类之间的关系配置到配置文件中,而外观模式就是将他们的关系放在一个Facade类中,降低了类类之间的耦合度,该模式中没有涉及到接口, 而是用一个类顺序的调用其它类,使其它类之间没有任何依赖关系public class CPU{
public void startup(){ .....}
public void shutdown(){......}
}
public class Memory{
public void startup(){ .....}
public void shutdown(){......}
public class Disk{
public void startup(){ .....}
public void shutdown(){......}
public class Computer{
private CPU cpu;
private Memory memory;
private Disk disk;
public Computer(){
cpu = new CPU();
memory = new Memory();
disk = new Disk();
}
public void startup(){
cpu.startup();
memory.startup();
disk.startup();
}
public void shutdown(){
cpu.shutdown();
memory.shutdown();
disk.shutdown();
}
public class Test{
public static void main(String args[]){
Computer computer = new Computer();
computer.startup();
computer.shutdown();
}
10、桥接模式(Bridge)
桥接模式就是把事物和其具体实现分开,使他们可以各自独立的变化。桥接的用意是: 将抽象化与实现化解耦,使得二者可以独立变化,像我们常用的JDBC桥DriverManager一样,JDBC进行连接数据库的时候,在各个数据库之间进行切换,基本不需要动太多的代码,甚至丝毫不用动,原因就是JDBC提供统一接口,每个数据库提供各自的实现,用一个叫做数据库驱动的程序来桥接就行了.定义一个接口,创建二个具体类实现这个接口,再创建一个桥接抽象类提供setter and getter方法存取这个接口,最后创建桥具体类继承桥接抽象类并通过getter方法取得接口去调用接口中的方法。
public interface Driver{
void connect();
}
public class OracleDriver implements Driver{
public void connect(){.............}
}
public class SybaseDriver implements Driver{
public void connect(){.............}
public abstract class abstractBrigeDriver{
private Driver driver;
public void connect(){
driver.connect();
}
public Driver getDriver(){
return driver;
}
public void setDriver(Driver driver){
this.driver = driver;
}
}
public class BrigeDriver extend abstractBrigeDriver{
public void connect(){
getDriver().connect();
}
}
public void static main(String args[]){
Driver oracle = new OracleDriver();
Driver sybase = new SybaseDriver();
BrigeDriver brigeDriver = new BrigeDriver();
brigeDriver.setDriver(orace);
brigeDriver.connect();
brigeDriver.setDriver(sybase);
brigeDriver.connect();
}
}
11、组合模式(Composite)
组合模式有时又叫 部分-整体模式在处理类似树形结构的问题时比较方便。public class TreeNode{
private String name;
private TreeNode parent;
private Vector<TreeNode> children = new Vector<TreeNode>();
public TreeNode(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public TreeNode getParent(){
return parent;
}
public void setParent(TreeNode parent){
this.parent = parent;
}
public void addChildren(TreeNode treeNode){
children.add(treeNode);
}
public void removeChildren(TreeNode treeNode){
children.remove(treeNode);
}
public Enumeration<TreeNode> getChildren(){
return children.elements();
}
}
public class Tree{
TreeNode root = null;
public Tree(String name){
root = new TreeNode(name);
}
public static void main(String args[]){
Tree tree = new Tree("A");
TreeNode nodeB = new TreeNode("B");
TreeNode nodeC = new TreeNode("C");
nodeB.setParent(tree);
nodeC.setParent(tree);
tree.root.add(nodeB);
tree.root.add(nodeC);
TreeNode nodeB1 = new TreeNode("B1");
TreeNode nodeB2 = new TreeNode("B2");
nodeB1.setParent(nodeB);
nodeB2.setParent(nodeB);
nodeB.add(nodeB1);
nodeB.add(nodeB2);
}
}
12、享元模式(Flyweight)
享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。
public interface Flyweight{ void do();
}
public class Sub1FlyWeight implements Flyweight{
public void do(){....}
}
public class FactoryFlyWeight{
private static Map<String, Flyweight> map = new HashMap<String, Flyweight>();
public static FlyWeight produce(String name){
FlyWight flyweight = map.get(name);
if (flyweight ==null){
flyweight = new Sub1FlyWeight();
map.put(name, flyweight);
}
return flyweight;
}
public static int getSize(){
return map.size();
}
}
public class Test{
public static void main(String args[]){
Flyweight fly1 = FactoryFlyWeight.product("aa");
Flyweight fly2 = FactoryFlyWeight.product("aa");
Flyweight fly3 = FactoryFlyWeight.product("bb");
Flyweight fly4 = FactoryFlyWeight.product("bb");
System.out.println(FactoryFlyWeight.getSize());// the result is 2
}
}