转载于自己博客文章:
一、创建型设计模式
关注对象的创建,让一个类得到实例化过程由另一类的对象完成。
分类:工厂、生成器、原型、单列。
二、工厂模式
工厂模式包括简单工厂、工厂方法、抽象工厂,
新建一个工厂类,这个类专门为客户生产对象,即对象的创建由工厂完成
从用户的角度看,用户需要一个特定对象时,按以前的直接new的方式来创建,用户需为对象传入特点参数从而构造特定对象。但采用工厂模式后,对用户而言我们的工厂提供了几类对象,用户只需选择要什么类型的对象即可,不需要直接传入特点参数。
(1)、简单工厂模式:
将不同类型的对象放在一个工厂类中创建,用户只需用工厂对象调用不同的方法或传入不同的类型参数来获取对象。即一个工厂可以创建多种不同类型的对象。
但如果要增加对象类型,就要对工厂类进行更改,这违背了开放-封闭原则。
例如:
有一车类:
public class car {
String color; //颜色
int price; //价格
String brand;
}
奥迪车子类:
public class AD_car extends car {
AD_car(String color,int price) {
super.color=color;
super.price=price;
super.brand="奥迪";
}
}
比亚迪车子类:
public class BYD_car extends car{
BYD_car(String color,int price) {
super.color=color;
super.price=price;
super.brand="比亚迪";
}
}
造车工厂:
public class car_factory {
public car creat_AD_car() {
car car = new AD_car("白色",200000);
return car;
}
public BYD_car creat_BYD_car() {
BYD_car car = new BYD_car("黑色",400000);
return car;
}
}
用户:
public class user {
public static void main(String[] args) {
car_factory factory =new car_factory();
car AD = factory.creat_AD_car(); //由工厂产生
car BYD = factory.creat_BYD_car();
}
}
如上user中,对客户而言,不用自己考虑对象的创建需要哪些东西,只需要你选择那种对象即可。
(2)工厂方法模式
上面的简单工厂模式违背了开放-封闭原则,即开放扩展,封闭内部。即当车的类型增加时,如增加奔驰车,工厂类就要增加代码来实现创建奔驰,这就造成,更改工厂类的代码。
面对上述问题,既然面对增加车类型时,工厂要生产新增的车就必须升级工厂设备等,那么我们直接让工厂功能专一化,每个工厂只生产一种车型,那么当增加车型时,我们就直接在开办一家工厂就行呗。这样不会对生产其他车型的工厂做任何修改。这就是工厂方法设计模式。
既然这些工厂都是生产车的那么我们用一个接口来抽象。
相当于造船厂总部:
public interface car_factory {
public car creatcar();
}
下面就是生产特定类型的造车厂:
奥迪造车厂:
public class AD_carfactory implements car_factory {
public car creatcar() {
car car = new AD_car("白色",200000);
return car;
}
}
比亚迪造车厂:
public class BYD_carfactory implements car_factory{
public car creatcar() {
car car = new BYD_car("白色",200000);
return car;
}
}
用户:
public class user {
public static void main(String[] args) {
car_factory factory =new AD_carfactory();
car AD = factory.creatcar();
System.out.println(AD.brand);
factory = new BYD_carfactory();
car BYD = factory.creatcar();
System.out.println(BYD.brand);
}
}
可以看到,如果现在增加了一个奔驰类,那么直接写一个奔驰造车长类即可。但问题就来了,车的类型这么多,我们为每种类型的车都开一个造车厂,这花销是不是太大,在代码上看就是工厂类太多,这样反而增加了很多代码。这个问题就是抽象工厂模式要解决的问题。
(3)抽象工厂模式
为了解决上面工厂方法带来的工厂类太多问题,抽象工厂设计模式,就是对这些工厂类进行一个抽象,即分组。我们上面的造车工厂是按车的品牌来分的,即一个品牌一个工厂。那现在如果一个品牌不仅由轿车还有摩托车,显然轿车和模特车不能用一个类描述,现在如果品牌有:奥迪、比亚迪、奔驰,车型有:轿车、模特车;那么显然要六个类才能描述完,按工厂方法的设计模式,就要建六个工厂,但我们想一下,这六个类,可以大致分为两类:轿车、摩托车,那么我们只建两个工厂,一个轿车工厂,建造轿车(b包括奥迪、比亚迪、奔驰),另一个为摩托车工厂,建造摩托车,那么建造轿车和建造摩托车工厂都有建造奥迪、比亚迪、奔驰的模块,这将工厂抽象为接口,
public interface brandfactory {
public car creatAD();
public car creatBYD();
public car creatBC();
}
写两个工厂类去实现这个接口:
轿车工厂
public carfactory implements brandfactory {
public car creatAD() {
car car = new AD_car();
return car;
}
public car creatBYD() {
car car = new BYD_car();
return car;
}
public car creatBC() {
car car = new BC_car();
return car;
}
}
摩托车工厂
public motuocarfactory implements brandfactory {
public car creatAD() {
car car = new AD_motuocar();
return car;
}
public car creatBYD() {
car car = new BYD_motuocar();
return car;
}
public car creatBC() {
car car = new BC_motuocar();
return car;
}
}
用户
public class user {
public static void main(String[] args) {
brandfactory carfactory = new carfactory();
car ADcar = carfactory.creatAD();
car BYDcar = carfactory.creatBYD();
car BCcar = carfactory.creatBC();
brandfactory motuocarfactory = new motuocarfactory();
car ADmotuo = motuocarfactory.creatAD();
car BCmotuo = motuocarfactory.creatBC();
...
}
}
如上我们的工厂类只有两个,但可以实现六关类对象的创建,这就是抽象工厂设计模式。
三、生成器模式
将一个复杂对象的构建与表示分离,与工厂模式相似,但生成器强调对象的对象生成过程,,而工厂模式对象的生成时很简单的。生成器在生成对象时,将对象的生成装配过程细化,让一个对象的生成过程每一步都单独可控。
由于对象生成不是单独一步完成,则需要单独的一个管理者来事项对象生成没一步的控制,只是让每一步过程组合到一样,生成目标对象。
例如:
我们用生成器生成一台电脑:
电脑类:
public class Computer {
public String master; //主要信息
public String screen; //屏幕
public String keyboard; //键盘
public String mouse; //鼠标
public String audio; //音响
public void setMaster(String master) {
this.master = master;
}
public void setScreen(String screen) {
this.screen = screen;
}
public void setKeyboard(String keyboard) {
this.keyboard = keyboard;
}
public void setMouse(String mouse) {
this.mouse = mouse;
}
public void setAudio(String audio) {
this.audio = audio;
}
}
建立一个抽象的builder类:
public abstract class ComputerBuilder {
protected Computer computer;
public Computer getComputer() {
return computer;
}
public void buildComputer() {
computer = new Computer();
System.out.println("生成了一台电脑!!!");
}
public abstract void buildMaster();
public abstract void buildScreen();
public abstract void buildKeyboard();
public abstract void buildMouse();
public abstract void buildAudio();
}
实现两个具体的builder类,分别是惠普电脑的builder和戴尔电脑的builder
public class HPComputerBuilder extends ComputerBuilder {
@Override
public void buildMaster() {
// TODO Auto-generated method stub
computer.setMaster("i7,16g,512SSD,1060");
System.out.println("(i7,16g,512SSD,1060)的惠普主机");
}
@Override
public void buildScreen() {
// TODO Auto-generated method stub
computer.setScreen("1080p");
System.out.println("(1080p)的惠普显示屏");
}
@Override
public void buildKeyboard() {
// TODO Auto-generated method stub
computer.setKeyboard("cherry 青轴机械键盘");
System.out.println("(cherry 青轴机械键盘)的键盘");
}
@Override
public void buildMouse() {
// TODO Auto-generated method stub
computer.setMouse("MI 鼠标");
System.out.println("(MI 鼠标)的鼠标");
}
@Override
public void buildAudio() {
// TODO Auto-generated method stub
computer.setAudio("飞利浦 音响");
System.out.println("(飞利浦 音响)的音响");
}
}
//
public class DELLComputerBuilder extends ComputerBuilder {
@Override
public void buildMaster() {
// TODO Auto-generated method stub
computer.setMaster("i7,32g,1TSSD,1060");
System.out.println("(i7,32g,1TSSD,1060)的戴尔主机");
}
@Override
public void buildScreen() {
// TODO Auto-generated method stub
computer.setScreen("4k");
System.out.println("(4k)的dell显示屏");
}
@Override
public void buildKeyboard() {
// TODO Auto-generated method stub
computer.setKeyboard("cherry 黑轴机械键盘");
System.out.println("(cherry 黑轴机械键盘)的键盘");
}
@Override
public void buildMouse() {
// TODO Auto-generated method stub
computer.setMouse("MI 鼠标");
System.out.println("(MI 鼠标)的鼠标");
}
@Override
public void buildAudio() {
// TODO Auto-generated method stub
computer.setAudio("飞利浦 音响");
System.out.println("(飞利浦 音响)的音响");
}
}
实现一个director类:
public class Director {
private ComputerBuilder computerBuilder;
public void setComputerBuilder(ComputerBuilder computerBuilder) {
this.computerBuilder = computerBuilder;
}
public Computer getComputer() {
return computerBuilder.getComputer();
}
public void constructComputer() {
computerBuilder.buildComputer();
computerBuilder.buildMaster();
computerBuilder.buildScreen();
computerBuilder.buildKeyboard();
computerBuilder.buildMouse();
computerBuilder.buildAudio();
}
}
测试一下代码:
public class ComputerCustomer {
public static void main(String[] args) {
// TODO Auto-generated method stub
Director director = new Director(); //创建管理对象
ComputerBuilder hp = new HPComputerBuilder(); //创建HP生成器对象,里面已经由电脑对象的空引用
director.setComputerBuilder(hp); //传入要管理的生成器对象。
director.constructComputer(); //对象装配
Computer pc = director.getComputer(); //返回得到HP电脑对象
}
}
简单理解为:给出电脑的组成,通过对电脑的组成,我们抽象出一组电脑生产步骤,通过改变某个步骤的内容就能实现生成不同的电脑。将电脑生成过程看作一个抽象类或接口,我们只需要继承或实现就能得到不同电脑的生成过程,在用一管理来管理电脑生成的吗没一步就完成了对象的生成。
四、原型模式
基于一个已有的对象作为原型,克隆出许多对象。
拷贝对象
五、单例模式
保证一个类只有一个实例,提供一个访问它的一个全局访问点。
创建一个单例类:
public class SingleObject {
//创建 SingleObject 的一个对象
private static SingleObject instance = new SingleObject();
//让构造函数为 private,这样该类就不会被实例化
private SingleObject(){}
//获取唯一可用的对象
public static SingleObject getInstance(){
return instance;
}
public void showMessage(){
System.out.println("Hello World!");
}
}
获取全局访问点:
public class SingletonPatternDemo {
public static void main(String[] args) {
//不合法的构造函数
//编译时错误:构造函数 SingleObject() 是不可见的
//SingleObject object = new SingleObject();
//获取唯一可用的对象
SingleObject object = SingleObject.getInstance();
//显示消息
object.showMessage();
}
}