工厂模式(已体会到此模式的意义)
第二次体会:
让使用对象的一端,不需要知道对象的具体类名,只需要知道工厂类名。随便你对象类如何变化。
所以工厂模式不是基本碰不到。而是非常实用。如果需要的一个对象会变动。那么可以用工厂类来隔离变化。把变化放到工厂类中,而调用方只需要知道对外稳定的工厂类就可以。
当你面对一个会常修改的类,可以用工厂模式,让变化隔离到工厂类。
代码
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 }