23种设计模式(三)-对象创建
- Factory Method 工厂方法
模式定义:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:虚函数)到子类。
组件:
抽象工厂(AbstractFactory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
package com.lillcol.designmodel;
/**
* @author lillcol
* 2019/6/16-21:36
*/
public class FactoryMethod {
public static void main(String[] args) {
ConcreteFactory1 concreteFactory1 = new ConcreteFactory1();
Product product = concreteFactory1.newProduct();
product.show();
System.out.println("-------------------------------------------");
ConcreteFactory2 concreteFactory2 = new ConcreteFactory2();
Product product2 = concreteFactory2.newProduct();
product2.show();
}
}
abstract class Product {//定义了产品的规范,描述了产品的主要特性和功能
abstract void show();
}
class ConcreteProductA extends Product { //具体产品ProductA
@Override
void show() {
System.out.println("ConcreteProductA");
}
}
class ConcreteProductB extends Product { //具体产品ProductB
@Override
void show() {
System.out.println("ConcreteProductB");
}
}
abstract class AbstractFactory{ //提供了创建产品的抽象
abstract Product newProduct();
}
class ConcreteFactory1 extends AbstractFactory{ //实现抽象工厂中的抽象方法,完成具体产品的创建。
@Override
Product newProduct() {
return new ConcreteProductA();
}
}
class ConcreteFactory2 extends AbstractFactory{//实现抽象工厂中的抽象方法,完成具体产品的创建。
@Override
Product newProduct() {
return new ConcreteProductB();
}
}
//输出结果:
ConcreteProductA
-------------------------------------------
ConcreteProductB
工厂方法模式的优点:
用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;工厂方法模式的缺点:
每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。
- AbstractFactory 抽象工厂
模式定义:
定义一个接口,让该借口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
使用抽象工厂模式条件:
系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
系统一次只可能消费其中某一族产品,即同族的产品一起使用。
组件:
抽象工厂(AbstractFactory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
具体工厂(ConcreteFactory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。
package com.lillcol.designmodel;
/**
* @author lillcol
* 2019/6/16-22:38
*/
public class AbstractFactory {
public static void main(String[] args) {
ConcreteFactory1 concreteFactory1 = new ConcreteFactory1();
concreteFactory1.newProduct1().show();
concreteFactory1.newProduct2().show();
System.out.println("-----------------------------------------");
ConcreteFactory2 concreteFactory2 = new ConcreteFactory2();
concreteFactory2.newProduct1().show();
concreteFactory2.newProduct2().show();
}
}
//中国 飞机:J20 航母:辽宁舰
//美国 飞机:F22 航母:福特级航母
abstract class Product1 { //飞机
abstract void show();
}
class ConcreteProduct11 extends Product1 {//中国飞机
@Override
void show() {
System.out.println("中国 飞机:J20");
}
}
class ConcreteProduct12 extends Product1 {//美国飞机:F22
@Override
void show() {
System.out.println("美国 飞机:F22 ");
}
}
abstract class Product2 { //航母
abstract void show();
}
class ConcreteProduct21 extends Product2 {//中国 航母:辽宁舰
@Override
void show() {
System.out.println("中国 航母:辽宁舰");
}
}
class ConcreteProduct22 extends Product2 {//美国 航母:福特级航母
@Override
void show() {
System.out.println("美国 航母:福特级航母 ");
}
}
abstract class Factory {
abstract Product1 newProduct1();
abstract Product2 newProduct2();
}
class ConcreteFactory1 extends Factory {//中国
@Override
Product1 newProduct1() {
return new ConcreteProduct11();
}
@Override
Product2 newProduct2() {
return new ConcreteProduct21();
}
}
class ConcreteFactory2 extends Factory {//美国
@Override
Product1 newProduct1() {
return new ConcreteProduct12();
}
@Override
Product2 newProduct2() {
return new ConcreteProduct22();
}
}
//输出结果:
中国 飞机:J20
中国 航母:辽宁舰
-----------------------------------------
美国 飞机:F22
美国 航母:福特级航母
抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下:
可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
当增加一个新的产品族时不需要修改原代码,满足开闭原则。抽象工厂模式缺点:
当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。
- Prototype 原型模式
模式定义:
使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象
原型模式组件:
抽象原型类:规定了具体原型对象必须实现的接口。
具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
访问类:使用具体原型类中的 clone() 方法来复制新的对象。
package com.lillcol.designmodel;
/**
* @author lillcol
* 2019/6/17-21:48
*/
public class Prototype {
public static void main(String[] args) throws CloneNotSupportedException {
Realizetype realizetype = new Realizetype();
Realizetype clone = (Realizetype)realizetype.clonePrototype();
System.out.println("realizetype==clone? "+ (realizetype==clone));
}
}
abstract class AbstractPrototype implements Cloneable{
abstract Object clonePrototype() throws CloneNotSupportedException;
}
class Realizetype extends AbstractPrototype{
Realizetype(){
System.out.println("Real King of Monkey");
}
Object clonePrototype() throws CloneNotSupportedException {
System.out.println("fake King of Monkey");
return (Realizetype)super.clone();
}
}
//输出结果:
Real King of Monkey
fake King of Monkey
realizetype==clone? false
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。
在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。
- Builder 构建器
模式定义:
将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)。
建造者(Builder)模式组件:
产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个滅部件。
抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
具体建造者(ConcreteBuilder):实现 Builder接口,完成复杂产品的各个部件的具体创建方法。
指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
package com.lillcol.designmodel;
/**
* @author lillcol
* 2019/6/17-22:32
*/
//组装电脑
public abstract class Builder {
Product product = new Product();
abstract void buyKey();
abstract void buyMouse();
abstract Product returnComputer();
}
class ConcreteBuilder1 extends Builder {
@Override
void buyKey() {
product.setKey("ConcreteBuilder1 key :双飞燕无线鼠标");
}
@Override
void buyMouse() {
product.setMouse("ConcreteBuilder1 mouse :双飞燕机械键盘");
}
@Override
Product returnComputer() {
return product;
}
}
class ConcreteBuilder2 extends Builder {
@Override
void buyKey() {
product.setKey("ConcreteBuilder1 key :无线鼠标");
}
@Override
void buyMouse() {
product.setMouse("ConcreteBuilder1 mouse :雷柏机械键盘");
}
@Override
Product returnComputer() {
return product;
}
}
class Product {
String key;
String mouse;
public void setKey(String key) {
this.key = key;
}
public void setMouse(String mouse) {
this.mouse = mouse;
}
public void show() {
System.out.println(key + " " + mouse);
}
}
class Director {
Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public Product construct() {
builder.buyKey();
builder.buyMouse();
return builder.returnComputer();
}
}
class BuilderTest {
public static void main(String[] args) {
ConcreteBuilder1 concreteBuilder1 = new ConcreteBuilder1();
Director dirctor = new Director(concreteBuilder1);
Product product = dirctor.construct();
product.show();
System.out.println("-----------------");
ConcreteBuilder2 concreteBuilder2 = new ConcreteBuilder2();
Director dirctor2 = new Director(concreteBuilder2);
Product product2 = dirctor2.construct();
product2.show();
}
}
//输出结果:
ConcreteBuilder1 key :双飞燕无线鼠标 ConcreteBuilder1 mouse :双飞燕机械键盘
-----------------
ConcreteBuilder1 key :无线鼠标 ConcreteBuilder1 mouse :雷柏机械键盘
优点:
- 各个具体的建造者相互独立,有利于系统的扩展。
- 客户端不必知道产品内部组成的细节,便于控制细节风险。
缺点:
- 产品的组成部分必须相同,这限制了其使用范围。
- 如果产品的内部变化复杂,该模式会增加很多的建造者类。
参考文档:
http://c.biancheng.net/view/1364.html
李建忠23中设计模式