工厂模式的理解
最近在看设计模式的内容,比较常用的设计模式有很多,他们的应用通常是用来降低系统耦合度的,在初步了解了工厂模式之后,简单的通过代码实现了它的几种形式,我以图形为例,将三角形和正方形设为要生产的两种产品,分别去写在三种工厂模式下的实现,然后写下此篇博客加深记忆。
由于本人对其理解不深,因此可能存在某些谬误,希望大家指正交流,互相进步。
工厂模式分类
1.简单工厂模式
2.工厂方法模式
3.抽象工厂模式
简单工厂模式
我所理解的简单工厂模式是工厂根据调用时传入的参数进行判断创建哪种产品,所有的产品都对应一个工厂,产出何种产品是在工厂类中进行判断的。
SimpleFactory类代码实例
public class SimpleFactory {
String shapename;
public SimpleFactory(String shapename){
this.shapename=shapename;
}
public static Shape createShape(String str){
switch(str){
case "三角形":
return new triangle();
case "正方形":
return new square();
default:
return new triangle();
}
}
}
interface Shape{
public abstract void draw();
}
class triangle implements Shape{
@Override
public void draw(){
System.out.println("画一个三角形");
}
}
class square implements Shape{
@Override
public void draw(){
System.out.println("画一个四边形");
}
}
其中
Shape是产品实现的接口。
triangle和square是两种产品的具体类,都实现了Shape接口,重写了draw方法。
SimpleFactory类是我的工厂类,它的构造方法是获得传入的参数,然后通过switch case(或if else)找到要返回的产品种类。
Test类
public class Test {
public static void main(String[] args) {
System.out.println("使用简单工厂模式");
Shape shape=SimpleFactory.createShape("正方形");
shape.draw();
}
}
简单工厂模式其实并不能很好地达到解耦的目的,如果我们使用该模式时需要添加产品的类型的话,我们就必须修改SimpleFactory类的内容,增加一个case,这是违反了设计模式原则中的开放——封闭原则的。因此,简单工厂模式并不是一种合格的设计模式。
工厂方法模式
由于简单工厂模式的弊端,我们又设计了一种解耦更好的工厂模式,也就是工厂方法模式,在这种模式中我们让每种产品都有一个对应的工厂类,每个类只负责创建一种对象,这些工厂类都实现同一个接口并重写接口中的方法。
FactoryMethod类
interface IFactory{
public Shape create();
}
public class FactoryMethod {
}
class FactoryS implements IFactory{
Shape s;
public FactoryS(){
this.s=new square();
}
@Override
public Shape create(){
return this.s;
}
}
class FactoryT implements IFactory{
Shape t;
public FactoryT(){
this.t=new triangle();
}
@Override
public Shape create(){
return this.t;
}
}
其中Shape接口和其实现类依旧使用了在简单工厂模式中使用的两个实现类。
IFactory接口是工厂类要实现的接口。
FactoryT和FactoryS是两个工厂类,重写了接口的create方法。其构造方法得到一个对应产品对象,create方法返回该对象。
测试代码
System.out.println("使用工厂方法模式");
IFactory i=new FactoryT();
Shape shapetwo=i.create();
shapetwo.draw();
通过需求方调用不同的子类,返回一个工厂类对象,
然后调用create方法,返回一个对应产品,
调用draw方法实现产品的输出。
工厂方法模式很好的实现了解耦的目的,当我们需要增加产品时,只需要添加一个实现IFactory接口的实现类,就可以不用修改其他内容,很好的解释了开放扩展,封闭修改的开闭原则。
抽象工厂模式
在查看了部分资料之后,发现抽象工厂模式所解决的问题通常是产品族的问题,若想理解产品族,请查看这篇博文抽象工厂模式。
因为涉及到了一个二维的区别,因此我考虑了下决定给图形加入第二个属性,color,共红黄两色,这时候如果组合的话就发现有四种产品,但是我们将一个相同颜色看作是一个产品族的内容(有些牵强,在上面提到的博文中有以Window和Unix为产品族,以text和button为产品的分类,更加的直观一些,推荐可以好好看一下)。
现在假设我们只有两种产品,红色的三角形和黄色的正方形。
那么就会有如下设计。
AbstractFactory类
public abstract class AbstractFactory {
public abstract Triangle1 createTriangle();
public abstract Square1 createSquare();
}
class RedFactory extends AbstractFactory{
@Override
public Triangle1 createTriangle(){
return new RedTriangle();
}
@Override
public Square1 createSquare(){
return new RedSquare();
}
}
class YellowFactory extends AbstractFactory{
@Override
public Triangle1 createTriangle(){
return new YellowTriangle();
}
@Override
public Square1 createSquare(){
return new YellowSquare();
}
}
interface Triangle1{
public void say();
}
class RedTriangle implements Triangle1{
@Override
public void say(){
System.out.println("红色三角形");
}
}
class YellowTriangle implements Triangle1{
@Override
public void say(){
System.out.println("黄色三角形");
}
}
interface Square1{
public void say();
}
class RedSquare implements Square1{
@Override
public void say(){
System.out.println("红色正方形");
}
}
class YellowSquare implements Square1{
@Override
public void say(){
System.out.println("黄色正方形");
}
}
其中AbstractFactory类是抽象工厂类。
TriangleFactory类和SquareFactory类是他的两个扩展类,分别用来生产红色或黄色的图形,那么按照之前的约定,红色的同属一个产品族,黄色的同属一个产品族,就应当有四种工厂类。分别在两个工厂类中产出。
因为和之前SimpleFactory类中中定义的产品接口实现类冲突,所以我在新的产品接口后都加了个1,然后红色和黄色两个工厂接口下都有两个产品实现类,分别是其红色款和黄色款,在工厂方法中调用createTriangle()方法和createSquare()方法时直接返回对应产品,这就完成了一个抽象工厂模式的书写。
如果我们想再往其中加入产品族的话,就会发现必须修改所有的工厂类,因此抽象工厂的扩展是很难的。
System.out.println("使用抽象工厂模式,将工厂类划分成两层,抽象工厂层和具体的工厂子类层");
AbstractFactory redfactory=new RedFactory();
Square1 redsquare=redfactory.createSquare();
Triangle1 redtriangle=redfactory.createTriangle();
redsquare.say();
redtriangle.say();
AbstractFactory yellowfactory=new YellowFactory();
Square1 yellowsquare=yellowfactory.createSquare();
Triangle1 yellowtriangle=yellowfactory.createTriangle();
yellowsquare.say();
yellowtriangle.say();
输入如下:
红色正方形
红色三角形
黄色正方形
黄色三角形
PS:抽象工厂类这里可能理解的不是很透彻,以上仅代表个人意见。如果有谬误的话,欢迎指出交流。
总结
1.简单工厂模式更像是一种多态的使用,不具备真正的设计模式的优点
2.工厂方法模式比较常用,一个工厂负责生产一种产品,分工明确,是一种常用设计模式。
3.抽象工厂模式拓展了产品族的概念,一个类中可能不止一个方法来表示产品的参数,但还是生产一种产品。这种情况下如果要增加产品族的话需要对工厂类进行修改,难以扩展。