第二次体会:
让使用对象的一端,不需要知道对象的具体类名,只需要知道工厂类名。随便你对象类如何变化。
所以工厂模式不是基本碰不到。而是非常实用。如果需要的一个对象会变动。那么可以用工厂类来隔离变化。把变化放到工厂类中,而调用方只需要知道对外稳定的工厂类就可以。
当你面对一个会常修改的类,可以用工厂模式,让变化隔离到工厂类。
代码
package com.linson.android.hiandroid2.DesignPattern;
//基本很少用工厂,有什么是new不能解决的?
//1.参数太复杂,不想直接用new。
// 什么!!!难道不会提供一个简单的构造函数,使用默认值去调用复杂的构造函数吗?
//2.产品太多。到达上百,几千,几万个。new 一个东西。想不起来叫什么名字。
//这个倒是有需要。用工厂的静态方法就可以。没有必要到工厂方法。
//3.创建太复杂,需要先找很多信息。才能new.
//基本不可信,还是一样.用一个方法包一下就可以,就可以为什么要工厂?
//4.对象会变成一个新的对象,如果一变,所以new代码都需要修改。
//这个才是使用工厂模式的最佳场景。
import com.linson.LSLibrary.AndroidHelper.LSComponentsHelper;
import java.security.MessageDigest;
public class Factory
{
public static void Run()
{
//想要一本关于二战的书。但是有不同的书商可以生产,甚至以后可能会倒闭。所以我不想知道书商的信息。
//如果书商变化。那么所有涉及到书商的代码都要修改。所以才有了工厂模式。让工厂来使用书商,以后修改只需要修改工厂类。
//v1告诉工厂来建立。不需要知道是哪个书商提供的书。
FactoryBooks.createHistoryBook(1, "war", 2001);
//v2这里也是一样,反正都是把变化放到工厂里面。
FactoryHistroy factoryHistroy=new FactoryHistroy(1, "war", 2001);
factoryHistroy.create();
//v3.使用的方式可以很多中。但是根本思维是一致的。所以是工厂模式。
BookFactory bookFactory=new BookFactory();
bookFactory.createHistoryBook(1, "war", 2001);
}
public static abstract class BaseBook
{
public int mID;
public String mName;
public abstract String introduceMe();
}
public static class ScienceBook extends BaseBook
{
public String mCrazy="";
public ScienceBook(String crazy,int id,String name)
{
mCrazy=crazy;
mID=id;
mName=name;
}
@Override
public String introduceMe()
{
return "it is Science Book:"+mName+".id:"+mID+".crazy level:"+mCrazy;
}
}
public static class HistoryBook extends BaseBook
{
public int mYear;
public HistoryBook(int year,int id,String name)
{
mYear=year;
mID=id;
mName=name;
}
@Override
public String introduceMe()
{
return "it is HistoryBook.from class:HistoryBook. Book:"+mName+".id:"+mID+".year:"+mYear;
}
}
public static class HistoryBook2 extends BaseBook
{
public int mYear;
public HistoryBook2(int year,int id,String name)
{
mYear=year;
mID=id;
mName=name;
}
@Override
public String introduceMe()
{
return "it is HistoryBook.from class :HistoryBook2. Book:"+mName+".id:"+mID+".year:"+mYear;
}
}
//region factory function
public static interface FactoryB
{
public BaseBook create();
}
public static class FactoryHistroy implements FactoryB
{
public int mID;
public String mName;
public int mYear;
public FactoryHistroy(int id,String name,int year)
{
mID=id;
mName=name;
mYear=year;
}
@Override
public BaseBook create()
{
//return new HistoryBook(mYear, mID, mName);
return new HistoryBook2(mYear, mID, mName);
}
}
//endregion
//region factory
public static class BookFactory
{
public BaseBook createHistoryBook(int id,String name,int year)
{
return new HistoryBook2(year, id, name);
}
}
//endregion
//region static fun
public static class FactoryBooks
{
public static BaseBook createHistoryBook(int id,String name,int year)
{
//BaseBook historyBook=new HistoryBook2(year, id, name);
BaseBook historyBook=new HistoryBook(year, id, name);//这里是变化点。
return historyBook;
}
//public static HistoryBook createxxxxBook(int id,String name,int year)
//public static HistoryBook createxxxxBook(int id,String name,int year)
//public static HistoryBook createxxxxBook(int id,String name,int year)
//public static HistoryBook createxxxxBook(int id,String name,int year)
}
//endregion
}
第一次体会“
个人总结,基本碰不到必要用工厂模式,很多更简单的方法可以代替, 最多来应对 某类对象太多而记不住名字。
回想下,最可能的情况是写模块,有些非急迫的模块,是有可能用工厂模式,因为不知道到时候会怎么改,干脆抽象一下,简单实现这些非急迫模块,去赶紧去做急迫模块。等讨论有结果了,原来代码也不用改。工厂模式一套,新建立一个具体工厂。项目完全不受影响。
不过复习第一个设计模式。就回想起设计模式最重要的2点知识点了
1.设计模式的最高原则,对修改关闭,对扩展开放
2.最高原则的具体表现,把修改从函数内感到函数外,这里就是静态工厂(通过接口或虚类),进一步,把修改从类内,赶到类外,这里就是工厂方法(又是通过接口)。能更进一步,把修改从一模块赶到另一模块(通过mvc,mvvp等设计模式)。
还能进一步,吧修改从一个程序赶到另一程序(云开发?),还能再进一步,把修改从电脑赶到其他人脑?(WTF)
1.给我一本马克思主义哲学。 new xxx
2.给我一本革命的书。 facotry.createxxx
3.给我一个图书馆里员 xxfactory=new xxx. xxfactory.create.
package com.linson.android.hiandroid2.DesignPattern;
//基本很少用工厂,有什么是new不能解决的?
//1.参数太复杂,不想直接用new。
// 什么!!!难道不会提供一个简单的构造函数,使用默认值去调用复杂的构造函数吗?
//2.产品太多。到达上百,几千,几万个。new 一个东西。想不起来叫什么名字。
//这个倒是有需要。用工厂的静态方法就可以。没有必要到工厂方法。
//3.创建太复杂,需要先找很多信息。才能new.
//基本不可信,还是一样.用一个方法包一下就可以,就可以为什么要工厂?
//4.如果以后会更换对象的话。那么就需要工厂模式了。
//个人总结,基本碰不到必要用工厂模式,很多更简单的方法可以代替, 最多用工厂静态方法,来应对成百上千种对象,而记不住名字。
import com.linson.LSLibrary.AndroidHelper.LSComponentsHelper;
import java.security.MessageDigest;
//但是例子还是要做。以创建书为例子,
//书的种类太多,假设有1000种。科幻,经济,历史,,等等等等等等等等,
//每种类别有自己特有的信息,字段。但都要提供描述方法。
public class Factory
{
public static void Run()
{
//想要生成一本二战的历史书,但是不记得类名。
//BaseBook secondWar=new ?????
//用静态方法,依靠编译器的提示功能来选择需要建立的类。
BaseBook secondWar=FactoryBooks.createHistoryBook(1, "the secord world war", 2001);
LSComponentsHelper.LS_Log.Log_INFO(secondWar.introduceMe());
//或者彻底对修改关闭。使用工厂方法,加一本书,就加一个工厂。而不是到内部加一个方法。
//没有太大必要。已经是方法分离了,
// 对修改关闭原子。把修改从方法内部,变成了方法外部。而工厂方法是要把变化从方法外部,变成类的外部。
//为什么不把修改放到文件外部呢?为什么不放到程序外部呢?为什么不放到地球外部呢?
FactoryB factoryhisotry=new FactoryHistroy(2, "the secord world war", 2009);
BaseBook secondWar2=factoryhisotry.create();
LSComponentsHelper.LS_Log.Log_INFO(secondWar2.introduceMe());
}
public static abstract class BaseBook
{
public int mID;
public String mName;
public abstract String introduceMe();
}
public static class ScienceBook extends BaseBook
{
public String mCrazy="";
public ScienceBook(String crazy,int id,String name)
{
mCrazy=crazy;
mID=id;
mName=name;
}
@Override
public String introduceMe()
{
return "it is Science Book:"+mName+".id:"+mID+".crazy level:"+mCrazy;
}
}
public static class HistoryBook extends BaseBook
{
public int mYear;
public HistoryBook(int year,int id,String name)
{
mYear=year;
mID=id;
mName=name;
}
@Override
public String introduceMe()
{
return "it is Science Book:"+mName+".id:"+mID+".year:"+mYear;
}
}
//region factory function
public static interface FactoryB
{
public BaseBook create();
}
public static class FactoryHistroy implements FactoryB
{
public int mID;
public String mName;
public int mYear;
public FactoryHistroy(int id,String name,int year)
{
mID=id;
mName=name;
mYear=year;
}
@Override
public BaseBook create()
{
return new HistoryBook(mYear, mID, mName);
}
}
//endregion
//region static fun
public static class FactoryBooks
{
public static HistoryBook createHistoryBook(int id,String name,int year)
{
HistoryBook historyBook=new HistoryBook(year, id, name);
return historyBook;
}
//public static HistoryBook createxxxxBook(int id,String name,int year)
//public static HistoryBook createxxxxBook(int id,String name,int year)
//public static HistoryBook createxxxxBook(int id,String name,int year)
//public static HistoryBook createxxxxBook(int id,String name,int year)
}
//endregion
}