github:GitHub - QiuliangLee/pattern: 设计模式
概念
根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。
简单工厂模式、工厂方法模式和抽象工厂模式有何区别? - 知乎本篇详解简单工厂、工厂方法和抽象工厂,建议关注和收藏。在我们平常创建对象的时候,都是通过关键字 new…https://www.zhihu.com/question/27125796/answer/1615074467
开闭原则 ocp: —个软件实体,应该对扩展开放,对修改关闭
应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化
简单工厂:唯一工厂类,一个产品抽象类,工厂类的创建方法依据入参判断并创建具体产品对象。
工厂方法:多个工厂类,一个产品抽象类,利用多态创建不同的产品对象,避免了大量的if-else判断。
抽象工厂:多个工厂类,多个产品抽象类,产品子类分组,同一个工厂实现类创建同组中的不同产品,减少了工厂子类的数量。
需求分析
我想生产一批鼠标,鼠标品牌目前只有”联想“,”惠普“。惠普鼠标
没有工厂模式
缺点:不符合ocp
联想鼠标
public class LenovoMouse{public void build() {System.out.println("生产联想鼠标");}
}
惠普鼠标
public class HPMouse{public void build() {System.out.println("生产惠普鼠标");}
}
MouseDemo
package com.lql.factory.no;import com.lql.factory.entity.HpMouse;
import com.lql.factory.entity.LenovoMouse;
import com.lql.factory.enums.MouseEnum;public class MouseDemo {public void getMouse(Integer type) {if (MouseEnum.LENOVO_MOUSE.getCode().equals(type)) {LenovoMouse lenovoMouse = new LenovoMouse();lenovoMouse.build();} else if (MouseEnum.HP_MOUSE.getCode().equals(type)) {HpMouse hpMouse = new HpMouse();hpMouse.build();} else {throw new IllegalArgumentException("无效的鼠标:" + type);}}
}
简单工厂模式
定义一个工厂类,根据传入的参数的值不同返回不同的实例,使得产品类满足OCP
特点:被创建的实例具有共同的父类或接口
使用场景:
- 客户端不关心对象的创建过程
- 需要创建的对象较少,修改对象不符合开闭原则.
缺点:工厂不满足OCP
Mouse接口
package com.lql.factory.entity;public interface Mouse {void build();
}
LenovoMouse
package com.lql.factory.entity;public class LenovoMouse implements Mouse {@Overridepublic void build() {System.out.println("生产联想鼠标");}
}
HpMouse
package com.lql.factory.entity;public class HpMouse implements Mouse {@Overridepublic void build() {System.out.println("生产惠普鼠标");}
}
MouseEnum
package com.lql.factory.enums;import lombok.AllArgsConstructor;
import lombok.Getter;@AllArgsConstructor
@Getter
public enum MouseEnum {LENOVO_MOUSE(1, "联想鼠标"),HP_MOUSE(2, "惠普鼠标");private final Integer code;private final String desc;
}
MouseFactory
package com.lql.factory.simplefactory;import com.lql.factory.entity.HpMouse;
import com.lql.factory.entity.LenovoMouse;
import com.lql.factory.entity.Mouse;public class MouseFactory {public static Mouse createMouse(Integer type) {switch (type) {case 1:return new LenovoMouse();case 2:return new HpMouse();default:return new LenovoMouse();}}
}
工厂模式
定义一个用于常见对象的接口,让子类决定实例化哪一个类
对类的实例化延迟到其子类
特点:不违反开闭原则(增加联想鼠标,不用修改已有代码,增加新的接口,LenvoMouse和 LenvoMouseFactory)
缺点:
(1)添加子类的时候”拖家带口”
(2)只支持同一类产品的创建
MouseFactory
package com.lql.factory.factorymethod;import com.lql.factory.entity.Mouse;public interface MouseFactory {Mouse createMouse();
}
LenovoMouseFactory
package com.lql.factory.factorymethod;import com.lql.factory.entity.LenovoMouse;
import com.lql.factory.entity.Mouse;public class LenovoMouseFactory implements MouseFactory {@Overridepublic Mouse createMouse() {return new LenovoMouse();}
}
HpMouseFactory
package com.lql.factory.factorymethod;import com.lql.factory.entity.HpMouse;
import com.lql.factory.entity.Mouse;public class HpMouseFactory implements MouseFactory {@Overridepublic Mouse createMouse() {return new HpMouse();}
}
FactoryMethodDemo
package com.lql.factory.factorymethod;import com.lql.factory.entity.Mouse;public class FactoryMethodDemo {public static void main(String[] args) {MouseFactory mf = new HpMouseFactory();Mouse mouse = mf.createMouse();mouse.build();}
}
抽象工程模式
提供一个创建一系列相关或相互依赖对象的接口
(1)抽象工厂模式侧重的是同一产品族(比如鼠标和键盘,统一厂商)
(2)工厂方法模式更加侧重于同一产品等级(比如鼠标)
增加主板时还是违背开闭原则,可以采用spring ioc与工厂模式相结合的方式解决.
Keyboard
package com.lql.factory.entity;public interface Keyboard {void build();
}
LenovoKeyboard
package com.lql.factory.entity;public class LenovoKeyboard implements Keyboard {@Overridepublic void build() {System.out.println("生产联想键盘");}
}
HpKeyboard
package com.lql.factory.entity;public class HpKeyboard implements Keyboard {@Overridepublic void build() {System.out.println("生产惠普键盘");}
}
ComputerFactory
package com.lql.factory.absfactory;import com.lql.factory.entity.Keyboard;
import com.lql.factory.entity.Mouse;public interface ComputerFactory {Mouse createMouse();Keyboard createKeyboard();
}
LenovoComputerFactory
package com.lql.factory.absfactory;import com.lql.factory.entity.Keyboard;
import com.lql.factory.entity.LenovoKeyboard;
import com.lql.factory.entity.LenovoMouse;
import com.lql.factory.entity.Mouse;public class LenovoComputerFactory implements ComputerFactory {@Overridepublic Mouse createMouse() {return new LenovoMouse();}@Overridepublic Keyboard createKeyboard() {return new LenovoKeyboard();}
}
DellComputerFactory
package com.lql.factory.absfactory;import com.lql.factory.entity.DellKeyboard;
import com.lql.factory.entity.DellMouse;
import com.lql.factory.entity.Keyboard;
import com.lql.factory.entity.Mouse;public class DellComputerFactory implements ComputerFactory {@Overridepublic Mouse createMouse() {return new DellMouse();}@Overridepublic Keyboard createKeyboard() {return new DellKeyboard();}
}
AbstractFactoryDemo
package com.lql.factory.absfactory;import com.lql.factory.entity.Keyboard;
import com.lql.factory.entity.Mouse;public class AbstractFactoryDemo {public static void main(String[] args) {ComputerFactory cf = new HpComputerFactory();Mouse mouse = cf.createMouse();Keyboard keyboard = cf.createKeyboard();mouse.build();keyboard.build();}
}