生成复杂对象的地方,都可以考虑使用工厂模式。
角色简单工厂抽象产品具体产品 uml
代码案例产品接口
public interface FreshWaterFish { void grow();//鱼生长 void harvest();//收获鱼 }
具体的产品
public class Carp implements FreshWaterFish{ @Override public void grow() { System.out.println("鲤鱼在生长"); } @Override public void harvest() { System.out.println("捕获鲤鱼"); } }
简单工厂
public class SingleProductFactory { public static FreshWaterFish produceFish(String type){ if("草鱼".equals(type)){ return new GrassCarp(); }else if ("鲤鱼".equals(type)){ return new Carp(); } System.out.println("抱歉,暂无此品种的鱼"); return null; } }
调用
public static void main(String[] args) { FreshWaterFish GrassCrap = SingleProductFactory.produceFish("草鱼"); if(GrassCrap != null){ GrassCrap.grow(); GrassCrap.harvest(); } FreshWaterFish Crap = SingleProductFactory.produceFish("鲤鱼"); assert Crap != null; Crap.grow(); FreshWaterFish fish = SingleProductFactory.produceFish("黑鱼"); }优点
- 具体的对象从客户这边代码解耦服务端修改具体产品的类名,不影响使用
- 客户端要死记硬背,常量与产品的映射关系如果具体产品特别多,在简单工厂中代码回很臃肿
3. 要扩展具体产品的时候要修改简单工厂的代码,违反了开闭原则
- 抽象工厂具体工厂抽象产品具体产品
抽象的产品,也可以是接口
public abstract class Laptop { private String brand;//品牌 public Laptop(String brand) { this.brand = brand; } abstract public String getId(); public void getDescription(){ System.out.println("this is a " + brand +"Laptop"); } }
具体产品类
public class LenovoLaptop extends Laptop { private static final String brand = "LENOVO"; protected static int initId; public LenovoLaptop() { super(LenovoLaptop.brand); initId = 200; } @Override public String getId() { return "LENOVO--"+(initId++); } }
抽象的工厂
public interface LaptopFactory { Laptop produce();//生产笔记本电脑 void afterSaleService();//售后服务 }
具体工厂
public class LenovoFactory implements LaptopFactory { @Override public Laptop produce() { return new LenovoLaptop(); } @Override public void afterSaleService() { System.out.println("欢迎到来联想服务售后热线"); } }
调用
public static void main(String[] args) { LaptopFactory f1 = new LenovoFactory(); Laptop produce = f1.produce(); f1.afterSaleService(); produce.getDescription(); System.out.println(produce.getId()); }优点
- 依然具有简单工厂模式的优点,服务端修改具体的类名,客户端可以不用知道当产品要扩展一个新类的时候不用修改原来的代码(**ps:**可以用简单工厂模式包装工厂模式)
- 当我们使用工厂方法的时候,客户端不是依赖与具体的工厂吗,如果服务端修改工厂名,客户端也要修改?
工厂的名字,是视为接口的。作为作者有责任保正工厂的名字是稳定的。 缺点
- 当我们新增产品时,还需要提供对应的工厂类,系统中类的个数将会成倍增加,相当于增加了系统的复杂性
- **产品等级:**实现产品接口所创建的所有产品(产品的继承结构)。**产品族:**一个工厂生产的一系列产品。
抽象工厂具体工厂抽象产品具体产品 uml
代码案例抽象产品类
public abstract class Laptop { private String brand; public Laptop(String brand) { this.brand = brand; } abstract public String getId(); public void getDescription(){ System.out.println("this is a"+ brand+"Laptop"); } }
public abstract class MobilePhone { abstract void activate(); }
产品
public class AcerLaptop extends Laptop{ private static final String brand ="ACER"; private static int initId; public AcerLaptop() { super(brand); initId = 100; } @Override public String getId() { return "ACER--"+(initId++); } }
public class AcerPhone extends MobilePhone{ @Override void activate() { System.out.println("宏基手机被激活"); } }
抽象工厂
public interface AbstractFactory { MobilePhone getMobilePhone(); Laptop getLaptop(); }
工厂
public class AcerFactory implements AbstractFactory { @Override public MobilePhone getMobilePhone() { return new AcerPhone(); } @Override public Laptop getLaptop() { return new AcerLaptop(); } }优点
- 任有简单工厂和工厂方法的优点把抽象工厂减少了,无论有多少产品等级,抽象工厂只有一套
- 当产品等级发生变化时,以前的产品的工厂代码也要修改。违反开闭原则
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)