简单工厂模式

来源:互联网 发布:java线程注入service 编辑:程序博客网 时间:2024/06/16 02:09

package tarenaday25;
移动硬盘类
public class MobleStorage {
    public byte[]read(){
        System.out.println("从移动硬盘读取数据");
        return null;
    }
    public void write(byte[]data){
        System.out.println("向移动硬盘写入数据");
    }
}
package tarenaday25;
闪存类
public class FastDisk {
public byte[]read(){
    System.out.println("从闪存读取数据");
    return null;
}
public void write(byte[]data){
    System.out.println("向闪存写入数据");
}
}

计算机类

package tarenaday25;

public class Computer {
private FastDisk fastDisk;
private MobleStorage mobleStorage;
public FastDisk getFastDisk() {
    return fastDisk;
}
public void setFastDisk(FastDisk fastDisk) {
    this.fastDisk = fastDisk;
}
public MobleStorage getMobleStorage() {
    return mobleStorage;
}
public void setMobleStorage(MobleStorage mobleStorage) {
    this.mobleStorage = mobleStorage;
}
public void readFromFastDisk(){
    fastDisk.read();
}
public void readFromMobileStoreage(){
    mobleStorage.read();
}
}





可不可以不使用接口,一个一个类的去写,从实现的角度上是可以的,但是为什么我们不让大家这样做呢,因为他不满足面向对象的一个基础原则,开闭原则,开闭原则很出名的,什么是开闭原则呢?说的专业一点,开闭原则:对扩展开放对修改关闭。说的直白点,就是程序应当是可扩展性的,并且不应该因功能扩展导致原有代码的修改。那么根据这个原则,大家想象一下,如果我们增加新的磁盘,这个时候是不是我们还要添加新磁盘的get set方法,实现扩展了,但是却对原有代码进行了修改,而我们昨天的写法是怎么写的,添加了一个接口,其实,注意下,要想实现开闭原则,最好的方式就是抽象,抽象出接口或者抽象类来,就能有效的解决这个问题。大家看下,我在代码里面添加一个接口。代码展示。

package tarenaday25;

public interface Idisk {
     byte[]read();
     void write(byte[]data);
}

加上一个接口,其他类去实现这个接口。

大家看一下,这个就是我们我们刚刚用代码实现那个项目,之前的办法很不可取,现在我们加了一个接口,首先是定义了一个接口,里面两个方法,read write ,底下有两个实现类,flashdisk,,,这两个都实现了相同的接口,这个就是我们现在做的事情,我们做的就是在两个高度相似的类里面抽象出共同的接口,好处就是实现了开闭原则,这个是我们的computer类,在这个类里面,我们就可以以接口类型为对象,这个时候无论后面拓展多少种磁盘,只要符合这个接口规范,我们都可以插到计算机上面,里面的成员变量就一个,相对应的get set方法也是不需要更改原有代码。

 

其实呢,开闭原则是面向对象设计原则中最基本的原则,那么正式基于这样一个原则,我们很多的设计模式都是按照这个设计的,比如说今天我们要介绍的就是简单工厂模式,那么他是为了解决什么问题的,我们还是从错误的代码写起。简单工厂要解决的问题,上代码。


package tarenaday02;
水果接口
public interface IFruit {
void plant();
void grow();
void harvest();
}


橘子类
package tarenaday02;

public class Orange implements IFruit{
public void plant(){
    System.out.println("橘子种植");
}
public void grow(){
    System.out.println("橘子成长 ");
}
public void harvest(){
    System.out.println("橘子收获");
}
}

苹果类

 package tarenaday02;

public class Apple implements IFruit{
public void plant(){
    System.out.println("苹果种植");
}
public void grow(){
    System.out.println("苹果成长 ");
}
public void harvest(){
    System.out.println("苹果收获");
}
}


测试类

package tarenaday02;

public class Test {
public static void main(String[] args) {
   IFruit iFruit=new Apple();
    Test.show(iFruit);
    
}
public static void show(IFruit iFruit){
    iFruit.plant();
    iFruit.grow();
    iFruit.harvest();
}

}


这个时候我还想再加一个香蕉类,然后我们展示香蕉的生长周期,这个时候我们是不是还要在test类里面添加一个show方法,对吧,那么这样做的话,大家看一下,可以实现拓展了,那么是不是对原有代码进行了修改,不符合开闭原则,那么这个时候我们添加一个fruit的接口,我们把生长收获的方法都抽象出来,这样我们只需要在test中show方法里面传一个接口类型,那么这样就省去了很多的代码量,而且不需要对原有代码进行修改,接下来我们对代码进行一下修改。这个时候test是不是就省事了,就一个show方法。从这段代码来看是符合开闭原则,那在问一个问题,是整个类里面都实现了开闭原则了吗?

这里是不符合的,

IFruit iFruit=new Apple();
    Test.show(iFruit);

那么怎么解决这个问题呢,就是今天的简单工厂模式,工厂嘛,就是生产产品的,在这里呢就是解决对象的创建问题。不管以后创建多少种水果,我们只需要调用一下,就可以得到我要的水果。


package tarenaday02;

public class IFfactory {
    public static IFruit creat(int type){
        IFruit iFruit=null;
        switch (type) {
        case 1:
            iFruit=new Apple();
            break;
        case 2:
            iFruit=new Orange();
            break;
        case 3:
            iFruit=new Banana();
            break;
        }
        return iFruit;
        
    }

}

package tarenaday02;

public class Test {
public static void main(String[] args) {
    IFruit iFruit=new Apple();
    Test.show(IFactory.creat(0));
    
    
}
public static void show(IFruit iFruit){
    iFruit.plant();
    iFruit.grow();
    iFruit.harvest();
}

}

这样就好了。

大家都知道,以后我们从事开发工作,是很多人共同参加的,那么比如说,我是一个程序员,我负责写水果类,搞了一个接口,三个水果实现类,之前呢,可能我们做到这一步就好了,我的下游程序员就可以使用我写的这个接口,这样就算是已经不错了,对于我的下游程序员,需要知道有多少种水果吗?不用,他只需要关心这个接口就行了,关心拿到水果就行了,然后水果可以演示生长过程。至于有多少种水果,他不关心,就算添加50种,对于下游程序员有影响吗?没有,那么这个设计就算是很好了,但是,我们后来发现,我们增加50种水果,他在这里new的时候就需要new50种水果,它在创建的时候就需要知道有多少种水果,都是什么水果可以供我创建。这个对他来讲,学习起来太复杂了,这个时候,我们需要在这个基础行创建一个工厂,作用是当下游程序员调用这个工厂的时候就会返回一个合适的水果,也就是创建水果的过程由我来创建,下游程序员只需要调用我工厂里面水果的创建方法就行了。而且他不用关心水果是怎么创建的。

我们这时候只需要调用factory.creat()方法给你一个水果,124,这样还是需要客户程序员去记123都是代表什么水果,后面我们学习枚举后,就是变成Fruit.apple这样就省了很大的学习量。这样的话,我们发现,客户程序员的学习成本就很低了,而且代码也更加稳定了。将来以后不论你添加多少种水果,他里面的代码不需要太大的改变。这就是简单工厂模式。

那么这样就真的彻底符合开闭原则了吗?其实我们是把不符合开闭原则的代码添加到工厂里面了。这个等大家学了反射就能解决了,配合着字符串。

0 0
原创粉丝点击