背景
最近看了一篇挺有意思的漫畫https://blog.csdn.net/bjweimengshu/article/details/108459337?utm_medium=distribute.pc_feed.none-task-blog-personrec_tag-7.nonecase&depth_1-utm_source=distribute.pc_feed.none-task-blog-personrec_tag-7.nonecase&request_id=5f6000f2dfc5717f9a0d7742,看了之后還是覺得基礎知識不牢固,所以還是寫一篇博客,學習以及分享一下工廠模式。
工廠模式
工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一。這種類型的設計模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。
在工廠模式中,我們在創(chuàng)建對象時不會對客戶端暴露創(chuàng)建邏輯,并且是通過使用一個共同的接口來指向新創(chuàng)建的對象。
正如漫畫中所說的那樣,當一個類的初始化方法過于復雜的時候,如果直接寫在這個類的構造函數(shù)里面,會使得代碼的可讀性可可擴展性大大降低,這個時候,工廠類應運而生。
簡單工廠模式
代碼例子引自菜鳥教程。
public interface Shape {
void draw();
}
public class Circle implements Shape{
@Override
public void draw() {
System.out.println("This is Circle.");
}
}
public class Rectangle implements Shape{
@Override
public void draw() {
System.out.println("This is Rectangle.");
}
}
public class Square implements Shape{
@Override
public void draw() {
System.out.println("This is Square.");
}
}
分別有三個形狀,創(chuàng)建工廠類,根據(jù)需要得到想要的形狀。
public class ShapeFactory {
public Shape getShape(String shapeType) {
if (shapeType == null) {
return null;
}
if (shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
} else if (shapeType.equalsIgnoreCase("SQUARE")) {
return new Square();
}
return null;
}
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
Shape circle = shapeFactory.getShape("CIRCLE");
circle.draw();
}
}
漫畫里面提出了一種開閉原則,指出了簡單工廠模式的缺點。
所謂面向對象的開放-封閉原則,就是在程序中對“擴展”開放,對“修改”封閉。如果每次業(yè)務改動都要增加新的if-else,就涉及對舊有代碼的修改,不但容易出錯,可讀性也不好。
工廠模式
為了避免上述簡單工廠模式的缺點,提出了工廠模式,工廠模式是對簡單工廠模式的進一步解耦。
public interface Shape {
void draw();
}
public class Circle implements Shape{
@Override
public void draw() {
System.out.println("This is Circle.");
}
}
public class Rectangle implements Shape{
@Override
public void draw() {
System.out.println("This is Rectangle.");
}
}
public class Square implements Shape{
@Override
public void draw() {
System.out.println("This is Square.");
}
}
首先創(chuàng)建Shape工廠接口。
public interface ShapeFactory {
Shape getShape();
}
三個形狀工廠類,分別實現(xiàn)該接口。
例如圓的工廠類:
public class CircleFactory implements ShapeFactory {
@Override
public Shape getShape() {
return new Circle();
}
}
如何獲取想要的形狀?
public class test {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
ShapeFactory circleFactory = (ShapeFactory) Class.forName("com.zhudan.factory.factorypattern.CircleFactory").newInstance();
Shape c = circleFactory.getShape();
c.draw();
}
}
這樣一來,當我想要增加一個新的形狀,就只需要新增相應的工廠類即可,而無需修改原來的代碼。
但是缺點也是顯而易見的,這樣的增加,開發(fā)難度明顯增加。
抽象工廠模式
同樣定義三個形狀類。
public interface Shape {
void draw();
}
public class Circle implements Shape{
@Override
public void draw() {
System.out.println("This is Circle.");
}
}
public class Rectangle implements Shape{
@Override
public void draw() {
System.out.println("This is Rectangle.");
}
}
public class Square implements Shape{
@Override
public void draw() {
System.out.println("This is Square.");
}
}
同樣定義顏色
public interface Color {
void fill();
}
public class Red implements Color {
@Override
public void fill() {
System.out.println("Inside Red::fill() method.");
}
}
public class Green implements Color {
@Override
public void fill() {
System.out.println("Inside Green::fill() method.");
}
}
public class Blue implements Color {
@Override
public void fill() {
System.out.println("Inside Blue::fill() method.");
}
}
創(chuàng)建抽象工廠AbstractFactory,ShapeFactory繼承AbstractFactory。
public abstract class AbstractFactory {
public abstract Color getColor(String color);
public abstract Shape getShape(String shape) ;
}
public class ShapeFactory extends AbstractFactory{
@Override
public Shape getShape(String shapeType) {
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
@Override
public Color getColor(String color) {
return null;
}
}
public class ColorFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
return null;
}
@Override
public Color getColor(String color) {
if(color == null){
return null;
}
if(color.equalsIgnoreCase("RED")){
return new Red();
} else if(color.equalsIgnoreCase("GREEN")){
return new Green();
} else if(color.equalsIgnoreCase("BLUE")){
return new Blue();
}
return null;
}
}
創(chuàng)建工廠創(chuàng)造器。
public class FactoryProducer {
public static AbstractFactory getFactory(String choice){
if(choice.equalsIgnoreCase("SHAPE")){
return new ShapeFactory();
}else if(choice.equalsIgnoreCase("COLOR")){
return new ColorFactory();
}
return null;
}
}
這樣就可以不用創(chuàng)建那么多的工廠類,只需要一個“工廠類創(chuàng)造器”就搞定了。
public class test {
public static void main(String[] args) {
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
Shape shape1 = shapeFactory.getShape("CIRCLE");
shape1.draw();
AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
Color color1 = colorFactory.getColor("RED");
}
}
這樣的好處,在于我可以隨意創(chuàng)建各種各樣的工廠,不需要局限于形狀的范圍,也可以創(chuàng)建顏色等等。
引自:
https://blog.csdn.net/u012156116/article/details/80857255