工厂模式:
—— 实现类生产者和调用者的一个分离
—— 详细分类:
1.简单工厂
2.工厂方法
3.抽象工厂
设计模式遵循原则
开闭原则:对扩展开放,对修改关闭
里氏代换原则:只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被覆用。而衍生类也能够在基类的基础上增加新的行为
依赖倒转原则:开闭原则的基础,对接口编程,依赖于抽象而不依赖于具体
接口隔离原则:使用多个隔离的接口来降低耦合度
迪米特法原则:最少知道原则。一个实体应该尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立
合成复用原则:尽量使用合成/聚合的方式,而不是使用继承。继承实际上破环了类的封装性,超类的方法可能会被子类修改。
简单工厂:
简单工厂也叫静态工厂,就是一个工厂生产所有的产品,根据用户传递的参数来生产不同的产品。
代码:
//鼠标基类
public abstract class Mouse {
abstract void click();
}
//戴尔鼠标类
public class DellMouse extends Mouse{
@Override
void click() {
System.out.println("戴尔鼠标");
}
}
//惠普鼠标类
public class HpMouse extends Mouse{
@Override
void click() {
System.out.println("惠普鼠标");
}
}
//鼠标工厂
public class MouseFactory {
public static Mouse createMouse(String type) {
if("戴尔".equals(type)) {
return new DellMouse();
}else if("惠普".equals(type)) {
return new HpMouse();
}else {
return null;
}
}
}
//客户端调用
public class Client {
public static void main(String[] args) {
Mouse dellMouse = MouseFactory.createMouse("戴尔");
Mouse hpMouse = MouseFactory.createMouse("惠普");
dellMouse.click();
hpMouse.click();
}
}
在普通的简单工厂模式下,所有产品都在一个工厂生产,用户可以根据不同的参数得到不同的产品,实现了生产者和调用者的分离,但是有一个问题无法解决,就是当需要增加新的产品的时候,需要去更改工厂类,这样就违反了开闭原则。所有就有了工厂方法模式。
工厂方法:
在该模式下,不同的产品由不同的子工厂去生产,所有的子工厂由一个工厂接口统一管理,生产产品时候不再由用户传来的参数决定,而是由工厂的类型决定,比如惠普工厂只生产惠普的鼠标,戴尔工厂只生产戴尔的鼠标。
具体代码如下:
//鼠标基类
public abstract class Mouse {
abstract void click();
}
//戴尔鼠标
public class DellMouse extends Mouse{
@Override
void click() {
System.out.println("戴尔鼠标");
}
}
//惠普鼠标
public class HpMouse extends Mouse{
@Override
void click() {
System.out.println("惠普鼠标");
}
}
//生产工厂
public interface MouseFactory {
Mouse createMouse();
}
//戴尔鼠标工厂
public class DellMouseFactory implements MouseFactory{
@Override
public Mouse createMouse() {
return new DellMouse();
}
}
//惠普鼠标工厂
public class DellMouseFactory implements MouseFactory{
@Override
public Mouse createMouse() {
return new DellMouse();
}
}
//客户端
public class Client {
public static void main(String[] args) {
//生产戴尔鼠标
DellMouseFactory dellMouseFactory = new DellMouseFactory();
Mouse dellMouse = dellMouseFactory.createMouse();
dellMouse.click();
//生产惠普鼠标
HpmouserFactory hpMouseFactory = new HpmouserFactory();
Mouse hpMouse = hpMouseFactory.createMouse();
hpMouse.click();
}
}
在该模式下的代码扩展性大大的提高了,当需要添加一种商品的时候,直接新增一个工厂的子类,让其实现总工厂的接口,但是在该模式下商品的生产变得更为复杂,必须先得到该商品的工厂,才能生产。
但是现在如果来了一个新的需求,客户不光是要鼠标了,他还订制了一批键盘,这个时候该怎么办呢?难道继续在鼠标的总工厂下增加子工厂?这样做显然是不合理的,这时候就涉及到产品族的概念,在新增产品族的时候,只有抽象工厂才能满足这种需求。
抽象工厂
抽象工厂,该模式下生产的产品可以多样化,同一品牌的工厂可以生产不同的产品,更好的解决产品族的一种模式。
具体代码如下:
//鼠标基类
public abstract class Mouse {
abstract void click();
}
//戴尔鼠标
public class DellMouse extends Mouse{
@Override
void click() {
System.out.println("戴尔鼠标");
}
}
//惠普鼠标
public class HpMouse extends Mouse{
@Override
void click() {
System.out.println("惠普鼠标");
}
}
//键盘基类
public abstract class KeyBoard {
abstract void kick();
}
//戴尔键盘
public class DellKeyBoard extends KeyBoard{
@Override
void kick() {
System.out.println("戴尔键盘");
}
}
//惠普键盘
public class HpkeyBoard extends KeyBoard{
@Override
void kick() {
System.out.println("惠普键盘");
}
}
//总工厂接口
public interface PcFactory {
Mouse createMouse();
KeyBoard createKeyBoard();
}
//戴尔工厂
public class DellFactory implements PcFactory {
@Override
public Mouse createMouse() {
return new DellMouse();
}
@Override
public KeyBoard createKeyBoard() {
return new DellKeyBoard();
}
}
//惠普工厂
public class HpFactory implements PcFactory{
@Override
public Mouse createMouse() {
return new HpMouse();
}
@Override
public KeyBoard createKeyBoard() {
return new HpkeyBoard();
}
}
//客户端调用
public class Client {
public static void main(String[] args) {
DellFactory dellFactory = new DellFactory();
Mouse dellMouse = dellFactory.createMouse();
KeyBoard dellKeyBoard = dellFactory.createKeyBoard();
dellMouse.click();
dellKeyBoard.kick();
System.out.println("================");
HpFactory hpFactory = new HpFactory();
Mouse hpMouse = hpFactory.createMouse();
KeyBoard hpKeyBoard = hpFactory.createKeyBoard();
hpMouse.click();
hpKeyBoard.kick();
}
}
但是抽象工厂也有它的缺点,如果要添加产品时,需要修改PcFactory、DellFactory、HpFactory等所有实现了PcFactroy接口的工厂类,这样大批量的改动显然是不友好的。