Design Patterns
github地址:https://github.com/XieXiePro/PatternDemo
一、Builder 模式
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以构建不同的表示。
Builder模式的使用场景:
(1)相同的方法,不同的执行顺序,产生不同的事件结果时。
(2)多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不同时。
(3)产品类非常复杂,或者产品类中的调用顺序不同产生了不同的作用,这个时候使用建造者模式非常合适。
(4)当初始化一个对象特别复杂,如参数多,且很多参数都有默认值时。
二、原型模式
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
原型模式的使用场景:
(1)类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗。
(2)通过new产生一个对象需要非常繁琐的h数据准备或者访问权限,这时可以使用原型模式。
(3)一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。
三、工厂模式
定义一个用于创建对象的接口,让子类决定实例化哪个类。
工厂模式的使用场景:
在任何需要生成复杂对象的地方,都可以使用工厂方法。复杂对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。
工厂模式通用模式代码:
/**
* 抽象产品类
*/
public abstract class Product{
/**
* 产品的抽象类
* 由具体产品去实现
*/
public abstract void method();
}
/**
* 具体产品类A
*/
public class ConcreteProductA extends Product{
@override
public void method(){
System.out.println("我是具体的产品A");
}
}
/**
* 具体产品类B
*/
public class ConcreteProductB extends Product{
@override
public void method(){
System.out.println("我是具体的产品B");
}
}
/**
* 抽象工厂类
*/
public abstract class Factory{
/**
* 抽象工厂方法
* 具体生产什么由子类去实现
* @return 具体的产品对象
*/
public abstract Product createProduct();
}
/**
* 具体工厂类
*/
public class ConcreteFactory extends Factory{
@override
public Product createProduct(){
return new ConcreteProductA();
}
}
/**
* 客户类
*/
public class Client{
public static void main(String[] args){
Factory factory =new ConcreteFactory();
Product p = factory.createProduct();
p.method();
}
}
这里的几个角色都很简单,主要分为四大模块,一是抽象工厂,其为工厂方法模式的核心;二是具体工厂,其实现了具体的业务逻辑;三是抽象产品,是工厂方法模式所创建的产品的父类;四是具体产品,为实现抽象产品的某个具体产品的对象。
上述的代码中我们在Client类中构造了一个工厂抽象,并通过其生产了一个产品对象,这里我们得到的产品对象是ConcreteProductA的实例,如果想得到ConcreteProductB的实例,更改ConcreteFactory中的逻辑即可:
public class ConcreteFactory extends Factory{
@override
public Product createProduct(){
return new ConcreteProductB();
//return new ConcreteProductA();
}
}
这种方式n比较常见,需要哪一个产品就生产哪一个,有时候也可以利用反射的方式更简洁的来生产具体产品对象,此时,需要d在工厂方法的参数列表中传入一个Class类来决定是哪一个产品类:
public abstract class Factory{
/**
* 抽象工厂方法
* 具体生产什么由子类去实现
*
* @param clz 产品对象类类型
*
* @return 具体的产品对象
*/
public abstract <T extends Product> T createProduct(Class<T> clz);
}
对于具体的工厂类,则通过反射获取类的示例即可:
public class ConcreteFactory extends Factory{
@override
public <T extends Product> T createProduct(Class<T> clz){
Product p = null;
try{
p = (Product)Class.forName(clz.getName()).newInstance();
}catch(Exception e){
e.printStackTrace();
}
return (T)p;
}
}
最后再看看Client中的实现:
public class Client{
public static void main(String[] args){
Factory factory =new ConcreteFactory();
Product p = factory.createProduct(ConcreteProductB.class);
p.method();
}
}
需要哪一个类的对象就传入哪一个类的类型即可,这种方法比较简洁、动态,也可以尝试为每一个产品都定义一个具体的工厂,各司其职:
public class ConcreteFactoryA extends Factory{
@override
public Product createProduct(){
return new ConcreteProductA();
}
}
public class ConcreteFactoryB extends Factory{
@override
public Product createProduct(){
return new ConcreteProductB();
}
}
public class Client{
public static void main(String[] args){
Factory factoryA =new ConcreteFactoryA();
Product productA = factoryA.createProduct();
productA.method();
Factory factoryB =new ConcreteFactoryB();
Product productB = factoryB.createProduct();
productB.method();
}
}
像这样拥有多个工厂的f方式我们称为多工厂方法模式。
当我们的工厂只有一个的时候,我们还是为工厂提供了一个抽象类,如果确定你的工厂类只有一个,那么简化掉抽象类是肯定没问题的,我们只需要将对应的工厂方法改为静态方法即可:
public class Factory{
public static Product creteProduct(){
return new ConreteProductB();
}
}
像这样的方式称为简单工厂模式或静态工厂模式,它是工厂方法模式的一个弱化版本。
四、抽象工厂模式
为创建一组相关或者是相互依赖的对象提供一个接口,而不需要指定它们的具体类。
抽象工厂模式的使用场景:
一个对象族有相同的约束时可以使用抽象工厂模式。
抽象工厂模式通用模式代码:
/**
* 抽象产品类A
*/
public abstract class AbstractProductA{
/**
* 每个具体的产品子类需要实现的方法
*/
public abstract void method();
}
/**
* 抽象产品类B
*/
public abstract class AbstractProductB{
/**
* 每个具体的产品子类需要实现的方法
*/
public abstract void method();
}
/**
* 具体产品类A1
*/
public class ConcreteProductA1 extends AbstactProductA{
@override
public abstract void method(){
System.out.println("具体产品A1的方法");
}
}
/**
* 具体产品类A2
*/
public class ConcreteProductA2 extends AbstactProductA{
@override
public abstract void method(){
System.out.println("具体产品A2的方法");
}
}
/**
* 具体产品类B1
*/
public class ConcreteProductB1 extends AbstactProductA{
@override
public abstract void method(){
System.out.println("具体产品B1的方法");
}
}
/**
* 具体产品类B2
*/
public class ConcreteProductB2 extends AbstactProductA{
@override
public abstract void method(){
System.out.println("具体产品B2的方法");
}
}
/**
* 抽象工厂类
*/
public abstract class AbstractFactory{
/**
* 创建产品A的方法
*
* @return 产品A对象
*/
public abstract AbstractProductA createProductA();
/**
* 创建产品B的方法
*
* @return 产品B对象
*/
public abstract AbstractProductB createProductB();
}
/**
* 具体工厂类1
*/
public class ConcreteFactory1 extends AbstractFactory{
@override
public AbstractProductA createProductA(){
return new ConcreteProductA1();
}
@override
public AbstractProductB createProductB(){
return new ConcreteProductB1();
}
}
/**
* 具体工厂类2
*/
public class ConcreteFactory2 extends AbstractFactory{
@override
public AbstractProductA createProductA(){
return new ConcreteProductA2();
}
@override
public AbstractProductB createProductB(){
return new ConcreteProductB2();
}
}
虽然抽象工厂方法模式的类繁多,但是,主要还是分为4类。
AbstractFactory:抽象工厂角色,它声明了一组用于创建一个产品的方法,每个方法对应一种产品。
ConcreteFactory:具体工厂角色,它实现了抽象工厂中定义的创建产品的方法,生成一组具体产品,这些产品构成了一个产品种类,每一个产品都位于某个产品等级结构中。
AbstractProduct:抽象产品角色,它为每种产品声明接口。
ConcreteProduct:具体产品角色,它定义具体工厂生产的具体产品对象,实现抽象产品中声明的业务方法。
虽然抽象工厂方法模式的类繁多,但是,主要还是分为4类。
AbstractFactory:抽象工厂角色,它声明了一组用于创建一个产品的方法,每个方法对应一种产品。
ConcreteFactory:具体工厂角色,它实现了抽象工厂中定义的创建产品的方法,生成一组具体产品,这些产品构成了一个产品种类,每一个产品都位于某个产品等级结构中。
AbstractProduct:抽象产品角色,它为每种产品声明接口。
ConcreteProduct:具体产品角色,它定义具体工厂生产的具体产品对象,实现抽象产品中声明的业务方法。
五、策略模式
策略模式定义了一系列算法,并将每一个算法封装起来,而且使用它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
网友评论