java23种设计模式—— 1、设计模式介绍
java23种设计模式—— 2、单例模式
java23种设计模式——3、工厂模式
java23种设计模式——4、原型模式
java23种设计模式——5、建造者模式
java23种设计模式——6、适配器模式java
工厂模式是咱们最经常使用的实例化对象模式了,是用工厂方法代替new操做的一种模式。著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统能够说是随处可见。由于工厂模式就至关于建立实例对象的new,咱们常常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来建立实例对象的,因此之后new时就要多个心眼,是否能够考虑使用工厂模式,虽然这样作,可能多作一些工做,但会给你系统带来更大的可扩展性和尽可能少的修改量。(百度百科)
工厂模式又分为:git
属于建立型模式,又叫作静态工厂方法模式,不属于23种GOF设计模式之一。是由一个工厂对象决定建立出哪种产品类的实例。违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会形成工厂逻辑过于复杂。github
假设如今有一家餐馆设计模式
public interface Restaurant { public void cook(); }
餐馆有两种菜品:红烧肉和鸡蛋羹bash
//鸡蛋羹 public class Egg implements Restaurant { @Override public void cook() { System.out.println("鸡蛋羹作好了"); } }
//红烧肉 public class Meet implements Restaurant{ @Override public void cook() { System.out.println("红烧肉作好了"); } }
餐馆里有服务员,来负责向后厨传达客人的需求iphone
public class Waiter { //一样能够定义常量而后经过switch语句来实现 public static Restaurant getFood(String orderType) { Restaurant restaurant = null; if(orderType.equals("红烧肉")){ restaurant = new Meet(); }else if (orderType.equals("鸡蛋羹")){ restaurant = new Egg(); } return restaurant; } }
如今顾客来了,要点一份红烧肉,就只须要和服务员说就行ide
public class Customer { public static void main(String[] args) { Restaurant restaurant = Waiter.getFood("红烧肉"); restaurant.cook(); } }
输出测试
红烧肉作好了
经过以上方法,的确实现了 提供建立实例的功能,而无需关心具体实现。可是咱们不难发现,这种方法的扩展性不好,若是餐馆新出了一款菜品,还须要咱们在服务员方法里修改。这使得当餐馆的菜品不少时,工厂方法代码逻辑将会很是复杂优化
工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式,经过定义工厂父类负责定义建立对象的公共接口,而子类则负责生成具体的对象。是在工厂模式家族中是用的最多模式,通常项目中存在最多的就是这个模式。是对简单工厂模式的一个优化,让每一个对象都有一个与之对应的工厂。
这里咱们接着用上面的例子,假设这家餐厅的生意很是好,因此餐馆的老板把餐馆全部负责点餐的服务员都辞退了,取而代之的是添加了一个收银台,而后让每一个厨师只负责作同样菜。这样客人只须要和收银台说要求就好了。
这里咱们接着用上面的类。除去服务员Waiter类
新建Cashier接口
/** * @author codermy * @createTime 2020/6/15 */ public interface Cashier { public Restaurant getFood(); }
而后给每个菜品新建一个工厂类
EggCooker
/** * @author codermy * @createTime 2020/6/15 */ public class EggCooker implements Cashier { @Override public Restaurant getFood() { return new Egg(); } }
MeetCooker
/** * @author codermy * @createTime 2020/6/15 */ public class MeetCooker implements Cashier{ @Override public Restaurant getFood() { return new Meet(); } }
而后顾客点单只须要在收银台,餐厅的系统会自动将信息传递给相应的厨师,对应的厨师就能在餐馆中把菜作好
/** * @author codermy * @createTime 2020/6/15 * 消费者 */ public class Customer { public static void main(String[] args) { Cashier order = new EggCooker(); Restaurant food = order.getFood(); food.cook(); } }
输出结果
鸡蛋羹作好了
工厂方法模式解决了简单工厂模式不符合的开闭原则,当添加一个菜品时,只须要再雇佣一个厨师就行(从现实角度看,老板有点亏哦)。可是这也增长了系统的复杂度(菜越多,厨师就越多,这哪家餐馆顶的住)
这个模式解决了每一个工厂只能建立一类产品(工厂方法模式)的问题
这里用餐馆的例子不太形象,不是很容易理解,强行举例可能会和上面的方法弄混,我本身绕了好一会,因此咱们换一个例子。
如今咱们人手不离手机,咱们假设手机有以下几个功能
//手机产品接口 public interface IphoneProduct { void callup();//打电话 void sendSms();//发短信 }
每一个人家里又都有路由器,路由器有以下功能
//路由器产品接口 public interface IRouterProduct { void openwifi();//开启wifi void setting();//设置wifi }
而后如今有一个抽象产品工厂,是来生产这两样产品的,假设生产手机和路由器的方法是同样的,只是须要加上厂商信息
//抽象产品工厂 public interface IProductFactory { //生产手机 IphoneProduct iphoneProduct(); //生产路由器 IRouterProduct iRouterProduct(); }
如今有两家厂商,小米和华为工厂,能够生产手机和路由器,他们两家厂商分别由两条产业线来作手机和路由器
//小米手机 public class XiaomiPhone implements IphoneProduct{ @Override public void callup() { System.out.println("用小米手机打电话"); } @Override public void sendSms() { System.out.println("用小米手机发短信"); } }
//小米路由器 public class XiaomiRouter implements IRouterProduct { @Override public void openwifi() { System.out.println("打开小米wifi"); } @Override public void setting() { System.out.println("设置小米wifi"); } }
//小米厂商 public class XiaomiFactory implements IProductFactory { @Override public IphoneProduct iphoneProduct() { return new XiaomiPhone(); } @Override public IRouterProduct iRouterProduct() { return new XiaomiRouter(); } }
//华为手机 public class HuaweiPhone implements IphoneProduct { @Override public void callup() { System.out.println("用华为手机打电话"); } @Override public void sendSms() { System.out.println("用华为手机发短信"); } }
//华为路由器 public class HuaweiRouter implements IRouterProduct { @Override public void openwifi() { System.out.println("打开华为wifi"); } @Override public void setting() { System.out.println("设置华为wifi"); } }
//华为工厂 public class HuaweiFactory implements IProductFactory { @Override public IphoneProduct iphoneProduct() { return new HuaweiPhone(); } @Override public IRouterProduct iRouterProduct() { return new HuaweiRouter(); } }
消费者类
//消费者/测试类 public class Customer { public static void main(String[] args) { System.out.println("==============小米产品================="); XiaomiFactory xiaomiFactory = new XiaomiFactory();//新建一个小米工厂 IphoneProduct xiaomiiphoneProduct = xiaomiFactory.iphoneProduct();//小米工厂开始生产小米手机 xiaomiiphoneProduct.callup();//测试小米手机打电话功能 IRouterProduct xiaomiiRouterProduct = xiaomiFactory.iRouterProduct();//小米工厂开始生产小米路由器 xiaomiiRouterProduct.openwifi();//测试小米路由器打开wifi功能 System.out.println("==============华为产品================="); HuaweiFactory huaweiFactory = new HuaweiFactory(); IphoneProduct huaweiiphoneProduct1 = huaweiFactory.iphoneProduct(); huaweiiphoneProduct1.callup(); IRouterProduct huaweiiRouterProduct = huaweiFactory.iRouterProduct(); huaweiiRouterProduct.openwifi(); } }
输出
==============小米产品================= 用小米手机打电话 打开小米wifi ==============华为产品================= 用华为手机打电话 打开华为wifi
抽象工厂模式相较于以上两种模式难以理解一些。这里提供另外一种写法比较好理解,来自Guide哥的博客(如下全部内容)
不知道你们玩过穿越火线或者吃鸡这类游戏了吗,游戏中存在各类枪。咱们假设如今存在AK、M4A1两类枪,每一种枪对应一种子弹。咱们如今这样考虑生产AK的工厂能够顺便生产AK使用的子弹,生产M4A1的工厂能够顺便生产M4A1使用的子弹。(AK工厂生产AK系列产品包括子弹啊,AK枪的类型啊这些,M4A1工厂同理)
————————————————
(1)建立相关接口:
枪
public interface Gun { public void shooting(); }
子弹
public interface Bullet { public void load(); }
(2)建立接口对应实现类:
AK类
public class AK implements Gun{ @Override public void shooting() { System.out.println("shooting with AK"); } }
M4A1类
public class M4A1 implements Gun { @Override public void shooting() { System.out.println("shooting with M4A1"); } }
AK子弹类
public class AK_Bullet implements Bullet { @Override public void load() { System.out.println("Load bullets with AK"); } }
M4A1子弹类
public class M4A1_Bullet implements Bullet { @Override public void load() { System.out.println("Load bullets with M4A1"); } }
(3)建立工厂接口
public interface Factory { public Gun produceGun(); public Bullet produceBullet(); }
(4)建立具体工厂
生产AK和AK子弹的工厂
public class AK_Factory implements Factory{ @Override public Gun produceGun() { return new AK(); } @Override public Bullet produceBullet() { return new AK_Bullet(); } }
生产M4A1和M4A1子弹的工厂
public class M4A1_Factory implements Factory{ @Override public Gun produceGun() { return new M4A1(); } @Override public Bullet produceBullet() { return new M4A1_Bullet(); } }
(5)测试
public class Test { public static void main(String[] args) { Factory factory; Gun gun; Bullet bullet; factory =new AK_Factory(); bullet=factory.produceBullet(); bullet.load(); gun=factory.produceGun(); gun.shooting(); } }
输出结果:
Load bullets with AK shooting with AK