工厂设计模式
工厂设计模式分为:简单工厂设计模式、静态工厂设计模式、抽象工厂设计模式,在这里我分为两种,就是简单工厂和抽象工厂。工厂模式是创建型模式,在创建对象实例时通过一个通用的工厂来生成对象,不允许将创建对象的代码分散于整个系统,适合于需要创建大量的实现了相同接口的类对象。基本原理就是,创建一个工厂类用其中的方法来管理生产,通过具体的类对象向上转型为基类对象并返回。
简单工厂设计模式
public interface Car {
void drive();
}
public class BMW implements Car{
public void drive() {
System.out.println("bmw drive");
}
}
public class Benz implements Car {
public void drive() {
System.out.println("benz drive");
}
}
public class CarFactory {
public Car produceCar(String type){
if("bmw".equals(type)){
return new BMW();
}else if("benz".equals(type)){
return new Benz();
}else{
System.out.println("do not hava this kind of car");
}
return null;
}
public static void main(String[] args) {
CarFactory carFactory = new CarFactory();
Car bmw = carFactory.produceCar("bmw");
Car benz = carFactory.produceCar("benz");
bmw.drive();
benz.drive();
}
// output: bmw drive
// benz drive
}
上面这种方式不够灵活,需要传入具体的类型参数标志,一旦传入有误则不能正常工作,更好的就是下面的静态工厂方法。
public class CarFactory {
public static Car produceBWM(){
return new BMW();
}
public static Car procudeBenz(){
return new Benz();
}
public static void main(String[] args) {
Car bmw = CarFactory.produceBWM();
Car benz = CarFactory.procudeBenz();
bmw.drive();
benz.drive();
}
// output: bmw drive
// benz drive
从上面的例子中可以发现简单工厂模式有一个缺点就是,扩展性不好,当需要创建一个新类型的对象,需要改动工厂类。如:现在我需要生产一台红旗汽车,就要在 CarFactory 添加一个方法,然而在实际中我们进行扩展时希望尽量不修改已有代码。抽象工厂就可以解决这个问题了。
抽象工厂设计模式
public interface CarFactory {
public Car produceCar();
}
public class BMWFactory implements CarFactory {
public Car produceCar() {
return new BMW();
}
}
public class BenzFactory implements CarFactory {
public Car produceCar() {
return new Benz();
}
}
public class FactoryTest {
public static void main(String[] args) {
CarFactory[] carFactorys={ new BMWFactory(),new BenzFactory()};
for(int i=0;i<2;i++){
carFactorys[i].produceCar().drive();
}
}
// output: bmw drive
// benz drive
}
现在需要生产红旗汽车,我们可以在这个基础上只需要创建新的 HongQiCar 和 HongQiCarFactory即可,并不需要改变其他类,可能有的人认为,直接在 CarFactory 添加一个系新方法不是更简单吗,不用又创建一个 HongQiCarFactory 类,的确局限于此是更简单,但是这样在使用到 car 对象(其实是派生类对象)的地方都要做相应的代码修改(没有充分利用多态),在一个复杂的系统中,这肯定是不划算的。
public class HongqiCar implements Car {
public void drive() {
System.out.println("hingqiCar drive");
}
}
public class HongQiCarFactory implements CarFactory {
public Car produceCar() {
return new HongqiCar();
}
}
public class FactoryTest {
public static void main(String[] args) {
CarFactory[] carFactorys={ new BMWFactory(),new BenzFactory(),new HongQiCarFactory()};
for(int i=0;i<3;i++){
carFactorys[i].produceCar().drive();
}
}
}
// output: bmw drive
// benz drive
// hingqiCar drive
单例模式
单例模式就是只允许在整个系统中创建一个实例对象,当然可以多个引用指向这个实例对象了。
public class ChinaSingleton {
private ChinaSingleton(){
System.out.println("世界只有一个中国,她叫中华人民共和国");
}
private static ChinaSingleton china= new ChinaSingleton();
public static ChinaSingleton newInstance(){
if(china != null){
return china;
}
return null;
}
public static void main(String[] args) {
ChinaSingleton.newInstance();
}
// output: 世界只有一个中国,她叫中华人民共和国
}
建造者模式(Builder设计模式)
我们都知道一个 java 对象,其中含有方法和属性,通常一个 java 对象了面有比较多的成员变量,我们在创建对象的时候,初始化这些属性通常有三种方式:在定义时进行初始化,在构造方法初始化,在使用前初始化。
注意:在 java 中,类中的成员变量默认初始化,在任何方法(包括构造方法)被调用前就已经完成,其中默认初始化为:
类型 | 默认值 |
---|---|
boolean | false |
int、float、double | 0、0.0f、0.0 |
char | 空字符 |
String | null |
对象 | null |
// 在定义时进行初始化
private Car car= new Car();
// 在构造方法中初始化
Factory(){
car = new Car;
}
// 在使用前初始化
method(){
car = new car;
car.drive();
}
而 Builder 设计模式,其实是在创建对象后初始化,即属于使用前初始化,这样做的好处就是不用通过在构造方法中初始化时,一般通过在构造方法传入参数然后初始化,但是对于一个类中的多个属性,有时我们只需要初始化一部分属性,而且初始化哪些属性还是不确定的,这就意味着我们需要重载多个构造方法来解决这个问题,但是这样就显得臃肿了。所以我们可以在创建对象后通过 setter 方法来设置初始化属性,Builder 设计模式就是 setter 的升级版本,代码简洁明了。
public class XiaoMiPhone {
private String battery;
private String screen;
private String cpu;
static class Builder{
private String defaultBattery ="5000毫安";
private String defaultScreen = "曲面屏";
private String defaultCpu = "晓龙";
XiaoMiPhone build(){
XiaoMiPhone xiaoMiPhone = new XiaoMiPhone();
xiaoMiPhone.battery = defaultBattery;
xiaoMiPhone.screen = defaultScreen;
xiaoMiPhone.cpu = defaultCpu;
return xiaoMiPhone;
}
Builder setBattery(String battery){
this.defaultBattery = battery;
return this;
}
Builder setScreen(String screen){
this.defaultScreen = screen;
return this;
}
Builder setCpu(String cpu){
this.defaultCpu = cpu;
return this;
}
}
public static void main(String[] args) {
XiaoMiPhone xiaoMiPhone = new XiaoMiPhone.Builder()
.setBattery("6000毫安")
.setScreen("钢化屏")
.build();
System.out.println(xiaoMiPhone.toString());
}
// output: XiaoMiPhone [battery=6000毫安, screen=钢化屏, cpu=晓龙]
小结: Java 设计模式一共有 23 种,这些都是历经考验的经典设计模式,如何历经考验我也不知道,因为我只是刚入门的小小菜鸟,但是我知道的是特定的问题特定场景,有特定的解决办法,我们需要基于这些设计原理灵活运用。上面我简单记录了工厂设计模式,单例模式,建造者模式,在理解和使用中会有偏差,在后面的学习中继续补充与更正,有不对的地方请指出,谢谢。
下一篇学习:ProtoType 模式,Adapter 模式,Observer 模式