设计模式之适配器模式、委派模式、访问者模式、工厂模式、桥接模式(双维度扩展)
设计模式之适配器模式、委派模式、访问者模式、工厂模式、观察者-发布订阅模式
- 设计模式分类:
- 适配器模式(Adapter Pattern)
- 定义
- 使用场景
- 代码实现
- 写法一:类适配器
- 写法二:对象适配器
- 实际应用例子
- 代码实现(版本一)
- 代码实现(版本二)
- 委派模式(delegate)
- 定义:
- 应用场景:
- 现实中的例子:
- 优缺点总结:
- 与代理模式的区别
- 代码实现
- 访问者模式(visitor)
- 定义
- 生活中的例子
- 适用场景
- 代码实现
- 基础数据结构
- 访问者
- 测试
- 优缺点总结
- 工厂模式(Factory Pattern)
- 简单工厂模式(Simple Factory)
- 定义:
- 使用场景:
- 优缺点:
- 代码实现:
- 工厂方法模式(Factory Method pattern)
- 定义
- 适用场景
- 优缺点
- 代码示例
- 抽象工厂(Abstract Factory)
- 定义
- 适用场景
- 优缺点
- 代码实现
- 代码实现
- 桥接模式(Bridge Pattern)
- 定义
- 适用场景
- 优缺点
- 代码实现
- 实际应用
- 观察者模式(Observer Pattern)
- 定义
- 适用场景
- 传统实现
- 发布主题以及实现
- 观察者实现
- 测试
- Guava 实现
- 实际应用
- 1.定义一个节点信息,用于存储基本信息以及后续扩展
- 2.定义观察者接口
- 3.定义一个节点管理器,用于实现注册和发布方法
- 4.应用一:实现指定的节点刷新接口
- 5. 应用二、派件给对应的人(通过抽象类注册)
设计模式分类:
适配器模式(Adapter Pattern)
定义
将一个类的接口变成客户端期望的另一种接口
使用场景
- 已经存在的类,他的方法和需求不匹配,
- 适配器模式不是软件设计阶段考虑的类,是由于随着软件的发展,不同产品,不同厂家功能类似、而接口不同的情况的解决方案。
总结:
适配器模式的局限性在于
1.原功能与期望的功能的输入参数和返回值要相同,即使不同也要有固定的关联关系
。
就像适配器经典例子中的电压一样,输入都是插头,输出都是电流。
代码实现
写法一:类适配器
类适配器采用继承的方式实现,暴漏了原方法给客户端,违法了最小职责原则,使用对象适配器能解决这一问题。
//原始类(已经存在的功能)
public class Origin {//已经存在的方法public int exitsMethod(){return 1;}
}//目标类(开发的新功能)
public interface Target {// 开发的新方法public Boolean expectMethod(String args);
}//测试
public class Test {public static void main(String[] args) {Adapter adapter = new Adapter();Boolean abc = adapter.expectMethod("abc");int i = adapter.exitsMethod(); //两个方法都暴漏给了客户端,不合适}
}// 适配器
public class Adapter extends Origin implements Target {@Overridepublic Boolean expectMethod(String args) {return exitsMethod() == 1;}
}
类图:
写法二:对象适配器
代码:
//原始类(已经存在的功能)
public class Origin {//已经存在的方法public int exitsMethod(){return 1;}
}//目标类(开发的新功能)
public interface Target {// 开发的新方法public Boolean expectMethod(String args);
}// 适配器
public class Adapter implements Target {private Origin origin;public Adapter(Origin origin) {this.origin = origin;}@Overridepublic Boolean expectMethod(String args) {return origin.exitsMethod() == 1;}
}//测试
public class Test {public static void main(String[] args) {Adapter adapter = new Adapter(new Origin());Boolean abc = adapter.expectMethod("abc");}
}
类图:
实际应用例子
需求:
现有登录方式:
- 用户名密码登录
需要新增如下第三方登录功能- 手机号验证码登录
- 微信登录
需要实现不同的厂商的同一登录功能。
代码实现(版本一)
//============= 现有功能代码===start=====//现有的用户名密码登录
public class PasswordLoginService {// 注册public Boolean register(String userId,String password){return true;}//用户密码登录public Boolean login(String userId,String password){return true;}
}//============= 现有功能代码===end=====//新增第三方登录接口
public interface ThirdPartyLogin {/** 手机号密码登录*/Boolean loginByPhone(String phone,String code);/**微信登录*/Boolean loginWechat(String openId);
}//适配器
public class PasswordForThirdPartyLoginAdapter extends PasswordLoginService implements ThirdPartyLogin{@Overridepublic Boolean loginByPhone(String phone, String code) {//缺少调用运营商校验验证码是否输入正确return this.loginForRegister(phone,null);}@Overridepublic Boolean loginWechat(String openId) {//缺少调用微信平台,校验openIdreturn this.loginForRegister(openId,null);}private Boolean loginForRegister(String userId,String password){if(password == null){password = "第三方登录,不需要密码";}if(super.register(userId,password)){super.login(userId,password);}return true;}
}//测试
public class Test {public static void main(String[] args) {PasswordForThirdPartyLoginAdapter adapter = new PasswordForThirdPartyLoginAdapter();adapter.login("用户命密码登录","密码");adapter.loginByPhone("13822992932","372652");adapter.loginWechat("wechatopenid");}
}
代码实现(版本二)
版本一有一些缺陷
适配器中缺少第三方的一些校验代码逻辑,实际开发中如果将对接第三方的代码写在这个适配器中将会变得十分臃肿。
// 原有的密码登录
public class PasswordLoginService {// 注册public Boolean register(String userId,String password){return true;}//用户密码登录public Boolean login(String userId,String password){return true;}
}public interface ThirdPartyLogin {/** 手机号密码登录*/Boolean loginByPhone(String phone,String code);/**微信登录*/Boolean loginWechat(String openId);
}//登录适配器接口,所有的第三方登录实现改接口
public interface LoginAdapter {Boolean support(LoginAdapter adapter);Boolean login(String userId,LoginAdapter adapter);
}//适配器(仅转接,不承接业务)
public class PasswordForThirdPartyLoginAdapter extends PasswordLoginService implements ThirdPartyLogin {@Overridepublic Boolean loginByPhone(String phone, String code) {return handleLogin(phone,new PhoneLoginAdapter());}@Overridepublic Boolean loginWechat(String openId) {return handleLogin(openId,new WechatLoginAdapter());}private Boolean handleLogin(String userId,LoginAdapter loginAdapter){if(loginAdapter.support(loginAdapter)){return loginAdapter.login(userId,loginAdapter);}return false;}}// 抽象登录适配器,作用:抽取公共的注册登录方法
public abstract class AbstractLoginAdapter extends PasswordLoginService implements LoginAdapter {protected Boolean loginForRegister(String userId,String password){if(password == null){password = "第三方登录,不需要密码";}if(super.register(userId,password)){super.login(userId,password);}return true;}
}//手机登录适配器
public class PhoneLoginAdapter extends AbstractLoginAdapter {@Overridepublic Boolean support(LoginAdapter adapter) {return adapter instanceof PhoneLoginAdapter;}@Overridepublic Boolean login(String userId, LoginAdapter adapter) {return super.loginForRegister(userId,null);}
}//微信登录适配器
public class WechatLoginAdapter extends AbstractLoginAdapter {@Overridepublic Boolean support(LoginAdapter adapter) {return adapter instanceof WechatLoginAdapter;}@Overridepublic Boolean login(String userId, LoginAdapter adapter) {return super.loginForRegister(userId,null);}
}//测试
public class Test {public static void main(String[] args) {PasswordForThirdPartyLoginAdapter adapter = new PasswordForThirdPartyLoginAdapter();adapter.login("用户命密码登录","密码");adapter.loginByPhone("13822992932","372652");adapter.loginWechat("wechatopenid");}
}
委派模式(delegate)
定义:
委派模式不属于GOF23种设计模式,是一种行为模式,与门面模式类似,不同的是委派模式是运行中
的行为处理逻辑。
委派模式更加注重委派的逻辑,而门面模式是一开始就定义好了的委托对象。
应用场景:
- 委派对象本身并不知道处理业务的逻辑,只是把请求交给其他程序来处理。
- 实现程序解耦
现实中的例子:
例如一个领导有很多下属,领导会跟进下属熟悉的领域进行安排工作,老板本身不参加具体事务。
优缺点总结:
委派模式能够将一个大型的任务拆分,更够通过管理子任务的执行情况解耦和提升效率。
与代理模式的区别
委派模式与代理模式也有很多相似之处,区别如下:
- 委派模式是行为模式,代理模式是结果模式
- 委派模式是任务派遣,注重结果;代理模式是代码增强,注重过程。
代码实现
代码
//员工接口
public interface Employee {void doSomething(String task);
}
public class EmployeeA implements Employee{@Overridepublic void doSomething(String task) {System.out.println("我擅长写报告...");}
}public class EmployeeB implements Employee{@Overridepublic void doSomething(String task) {System.out.println("我擅长公关...");}
}// 领导跟进员工的特征安排任务
public class Leader implements Employee {@Overridepublic void doSomething(String task) {if("接待".equals(task)){new EmployeeB().doSomething(task);} else if("汇报".equals(task)){new EmployeeA().doSomething(task);}}
}// 测试,老板发话给领导安排任务,领导找到员工
public class Boos {public void command(String task,Leader leader){leader.doSomething(task);}public static void main(String[] args) {new Boos().command("接待",new Leader());}
}
类图:
访问者模式(visitor)
定义
是一种将数据结构与数据操作分离的设计模式
生活中的例子
例如软件公司有若干码农,他们有一个共同的数据结构(姓名,KPI,bug数量,开发的功能,代码行数),对于不同的领导,如直属领导关注开发的功能,代码行数,开发部门经理关注程序员的bug数,公司CEO关注码农的KPI。
结合例子解释概念:
程序员的属性就是一个稳定的数据结构,公司的不同领导就是不同的访问者,他们关注的点(操作)各不相同。
适用场景
- 数据结构稳定、作用与数据结构的操作经常变化的操作
- 需要数据结构和数据操作分离的场景
代码实现
基础数据结构
#(一 员工抽象)
public abstract class Employee {//员工姓名private String name;//kpi分数private int kpi;public Employee(String name, int kpi) {this.name = name;this.kpi = kpi;}# 提供一个访问者进入的接口public abstract void accept(Visitor visitor);
}#(二 程序员实现)
public class Coder extends Employee {public Coder(String name, int kpi) {super(name, kpi);}@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}/*** 产生的bug数*/public Integer bugNumbers(){return new Random().nextInt(100);}
}
#(三 产品经理实现)
public class Manager extends Employee{public Manager(String name, int kpi) {super(name, kpi);}@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}/*** 经理考核上线的系统数量* @return*/public int systemCount(){return new Random().nextInt(10);}
}
访问者
# 访问者接口
public interface Visitor {// 访问员工void visit(Coder employee);* 访问经理*/void visit(Manager employee);
}# 访问者实现一:CTO
public class CTOVisitor implements Visitor {@Overridepublic void visit(Coder employee) {System.out.println("CTO看"+employee.getName()+"的bug数"+employee.bugNumbers());}@Overridepublic void visit(Manager employee) {System.out.println("CTO看"+employee.getName()+"的系统上线数"+employee.systemCount());}
}# 访问者实现二:CEO
public class CEOVisitor implements Visitor {@Overridepublic void visit(Coder employee) {System.out.println("CEO看"+employee.getName()+"的KPI"+employee.getKpi());}@Overridepublic void visit(Manager employee) {System.out.println("CEO看"+employee.getName()+"的KPI"+employee.getKpi());}
}
测试
public class Test {private static List<Employee> employeeList = new ArrayList();static {Coder coder = new Coder("张小开", 90);Manager manager = new Manager("李经理", 90);employeeList.add(coder);employeeList.add(manager);}public static void main(String[] args) {System.out.println("CTO===看员工");CTOVisitor ctoVisitor = new CTOVisitor();for (Employee employee : employeeList) {employee.accept(ctoVisitor);}System.out.println("CEO=====看员工");CEOVisitor ceoVisitor = new CEOVisitor();for (Employee employee : employeeList) {employee.accept(ceoVisitor);}}
}
优缺点总结
优点:
- 解耦的数据结构和数据的相关操作
- 随时扩展访问者对数据结构进行不同的数据操作
缺点:
- 如果数据结构不稳定,需要经常修改或删除则访问者需要做出对于的操作,违背开闭原则。
- 违背了依赖倒置原则,访问者依赖具体的对象,而没有依赖抽象。(如上述例子中访问者依赖了程序员、产品经理的具体实现,如果在增加一种员工类型则访问者接口又要增加一种访问类型,所有的访问者实现都需要调整)
总结:
访问者模式是一种比较复杂的设计模式,使用场景较少,数据行为类设计模式。
工厂模式(Factory Pattern)
简单工厂模式(Simple Factory)
定义:
是指由一个工厂根据不同的参数决定参加出那种产品。
使用场景:
- 需要创建的对象比较少
- 客户端只需要传入工厂类的参数,不需要关心创建对象的逻辑。
优缺点:
优点:只需要传入一个参数就可以获取想要的对象。
缺点:工厂类的职责过重,增加新的对象时需要修改创建工厂类的判断逻辑,违被了开闭原则
。
代码实现:
需求
根据不同的审批流程渠道获取申请人信息
实现代码:
public class CustomerSimpleFactory {public static CustomerInterface getInstance(String taskType){if("1".equals(taskType)){return new MainCustomerService();}else if("2".equals(taskType)){return new EleCustomerService();}else if("3".equals(taskType)){return new PreCustomerService();}else if("4".equals(taskType)){return new QrCustomerService();}return null;}public static CustomerInterface getInstance2(Class<? extends CustomerInterface> clazz){try {return clazz.newInstance();} catch (Exception e) {}return null;}
}
工厂方法模式(Factory Method pattern)
定义
定义一个工厂的接口,由子类实现工厂接口来决定创建的对象,工厂方法模式让类的实例推迟到子类工厂中
适用场景
1.创建对象需要由大量的逻辑,(实例化目标类时逻辑比较复杂)
2.预计有较多的新实例需要加入
优缺点
优点:
1.客户不需要知道类具体的创建细节 ,只需要关系返回的结果(与简单工厂一样有这个优点,似乎所有的工厂都是这个优点)
2.方便扩展新产品,符合开闭原则
缺点:
1.类的代码太多,增加了类的结构复杂度,2.增加了系统的抽象复杂度。
代码示例
/*** 工厂方法模式*/
public interface CustomerFactory {CustomerInterface getInstance();
}
/** 实现(一) 主流程 */
class MainCustomerFactory implements CustomerFactory{@Overridepublic CustomerInterface getInstance() {return null;}
}
/** 实现(二) 预决策 */
class PreCustomerFactory implements CustomerFactory{@Overridepublic CustomerInterface getInstance() {return null;}
}class Test{public static void main(String[] args) {CustomerFactory factory = new MainCustomerFactory();CustomerInterface instance = factory.getInstance();}
}
抽象工厂(Abstract Factory)
定义
指通过工厂创建一个具有产品,而同一个产品内有多个相互依赖或相关的接口。
比较绕口,举一个实际例子:总共有4个流程,其中每个流程都有获取申请人和担保人的方法。
适用场景
- 客户端需要依赖产品的创建细节
- 强调一系列相关的产品对象需要一起被创建
优缺点
优点:
1.具体产品在应用城代码隔离,无需关心具体创建细节
2.将一系列的产品主放在一起创建。(如:主流程申请人和主流程担保人在一起创建)
缺点:
1.产品中扩展新产品困难,需要修改抽象类,如新增一个联系人则需要修改抽象工厂方法,所有的子类都需要实现
2.类结构复杂,增加了系统的抽象性、复杂度。
代码实现
我们代码实现定义中举的例子:
总共有4个流程,其中每个流程都有获取申请人和担保人的方法。
分析:
1.工厂目标:客户端需要根据自己的需要,获取4个不同的流程产品对象。
2. 每一个产品对象都分别由获取申请人信息和担保人信息的方法(申请人和担保人相关的接口)
代码实现
//客户接口,以及不同流程的实现类
public interface Customer {}
class MainCustomer implements Customer{}
class PreCustomer implements Customer{}
//担保人接口,以及不同流程的实现类
public interface Guarantor {}class MainGuarantor implements Guarantor{}class PreGuarantor implements Guarantor{}
// 抽象工厂
public abstract class TaskFactory {public void init(){//一些初始化操作}public abstract Customer getCustomer();public abstract Guarantor getGuarantor();
}//主流程抽象工厂实现
class MainTaskFactory extends TaskFactory{@Overridepublic Customer getCustomer() {return new MainCustomer();}@Overridepublic Guarantor getGuarantor() {return new MainGuarantor();}
}//预批流程工厂实现
class PreTaskFactory extends TaskFactory{@Overridepublic Customer getCustomer() {return new PreCustomer();}@Overridepublic Guarantor getGuarantor() {return new PreGuarantor();}
}class Test {public static void main(String[] args) {TaskFactory factory = new MainTaskFactory();Customer customer = factory.getCustomer();Guarantor guarantor = factory.getGuarantor();}
}
桥接模式(Bridge Pattern)
定义
桥接模式又称双维度扩展模式,实际应用场景不太多。是将抽象部分与具体实现分离,使他们都可以独立变化。通过组合的方式将他们建立联系,而不是通过继承。
适用场景
一个类存在两个或多个独立变化的维度,且这两个维度都需要进行独立扩展。
举例:发送通知的方式有邮件、短信两种方式,而通过发送通知的方式又有加急、普通。
优缺点
优点:
1.分离抽象与具体
2.提高了系统的扩展性
3.复合开闭原则
缺点:
1.增加了系统的复杂度和设计难度
2.需要准确的识别系统中两个独立变化的维度(实际项目中难度较大)
代码实现
上面的例子【发送通知的方式有邮件、短信两种方式,而通过发送通知的方式又有加急、普通。】实现代码
public interface Message {void send(String message);
}class EmailMessage implements Message{@Overridepublic void send(String message) {System.out.println("发送邮件信息:"+message);}
}class PhoneMessage implements Message{@Overridepublic void send(String message) {System.out.println("发送手机短信信息:"+message);}
}
//抽象加急、普通短信桥接
public abstract class AbstractMessageBridge {private Message message;public AbstractMessageBridge(Message message){this.message = message;}public void send(String message) {this.message.send(message);}
}
//普通短信
class NormalMessage extends AbstractMessageBridge{public NormalMessage(Message message) {super(message);}@Overridepublic void send(String message) {super.send("[普通]"+message);}
}
//加急短信
class UrgentMessage extends AbstractMessageBridge{public UrgentMessage(Message message) {super(message);}@Overridepublic void send(String message) {super.send("[加急]"+message);}
}
// 测试
class Test {public static void main(String[] args) {AbstractMessageBridge message = new UrgentMessage(new EmailMessage());message.send("紧急休假");AbstractMessageBridge message2 = new NormalMessage(new EmailMessage());message2.send("休假");AbstractMessageBridge message3 = new NormalMessage(new PhoneMessage());message3.send("休假");}
}
实际应用
数据库驱动与操作数据的API
观察者模式(Observer Pattern)
定义
观察者模式又称发布订阅模式(Publish/Subscribe),定义一种一对多的依赖关系,一个主题对象可以被多个观察者同时监听,每当主题对象状态变化时,多依赖的对象都会被通知到。
适用场景
- 当一个或多个对象的变化依赖另一个对象的变化
- 实现类似的广播机制,发布者无需知道具体的收听者,感兴趣的对象会自动接受该广播
传统实现
发布主题以及实现
public interface Subject<E> {void addObserver(Observer<E> observer);/*** 通知对象* @param event*/void notify(E event);
}public class NodeCodeSubject implements Subject<String> {private List<Observer<String>> observers = new ArrayList<>();== 通知所有观察者@Overridepublic void notify(String event) {for (Observer<String> observer : observers) {observer.update(event);}}== 增加观察者的方法@Overridepublic void addObserver(Observer<String> observer) {observers.add(observer);}
}
观察者实现
public interface Observer<E> {/*** 观察者对象变化* @param event*/void update(E event);
}public class NodeCodeObserver implements Observer<String>{@Overridepublic void update(String event) {System.out.println("监听到节点变化了nodeCode:"+event);}
}
测试
public class Test {public static void main(String[] args) {NodeCodeObserver nodeCodeObserver = new NodeCodeObserver();NodeCodeObserver nodeCodeObserver2 = new NodeCodeObserver();Subject subject = new NodeCodeSubject();subject.addObserver(nodeCodeObserver);subject.addObserver(nodeCodeObserver2);subject.notify("end");}
}
Guava 实现
public class NodeCodeEvent {@Subscribepublic void assignee(String nodeCode){System.out.println("监听到nodeCode改变:"+nodeCode);}}# 测试
public class Test {public static void main(String[] args) {EventBus eventBus = new EventBus();eventBus.register(new NodeCodeEvent());eventBus.post("evl");eventBus.post("visit");}
}
实际应用
监听节点的变化来分别处理不同的逻辑同时满足一个观察者可以监听多个节点的功能,分别实现如:刷新接口,人工派件等功能。
1.定义一个节点信息,用于存储基本信息以及后续扩展
public class NodeInfo {private Long caseId;private String nodeCode;// ignore getting/setting
}
2.定义观察者接口
继承 InitializingBean 为了结合Spring使用,提醒子类主动注册观察者
public interface NodeObserver extends InitializingBean {/*** 需要监听的节点* @return*/List<String> registerCode();/*** 节点变化* @param nodeInfo*/void nodeChange(NodeInfo nodeInfo);}
3.定义一个节点管理器,用于实现注册和发布方法
public class NodeCodeManager {//注册的程序通过Key,Map存储到这里private static Map<String,List<NodeObserver>> map = new HashMap<>();public static void register(NodeObserver observer){for (String nodeCode : observer.registerCode()) {List<NodeObserver> list = null;if((list = map.get(nodeCode)) == null ){list = new ArrayList<>();}list.add(observer);map.put(nodeCode,list);}}/*** 节点变化,通知对应的节点* @param nodeInfo*/public static void notifyAll(NodeInfo nodeInfo){List<NodeObserver> list = map.get(nodeInfo.getNodeCode());if(list != null){for (NodeObserver nodeObserver : list) {nodeObserver.nodeChange(nodeInfo);}}}
}
4.应用一:实现指定的节点刷新接口
public class RefreshCoreService implements NodeObserver {@Overridepublic List<String> registerCode() {// 注册这两个节点作为这个类的观察节点,实现同时观察指定的多个接口return Arrays.asList("eval","vrf2");}@Overridepublic void nodeChange(NodeInfo nodeInfo) {System.out.println("现在的节点是:"+nodeInfo.getNodeCode());System.out.println("开始刷新接口.....");}@Overridepublic void afterPropertiesSet() throws Exception {//主动注册本实现作为观察者NodeCodeManager.register(this);}
}
5. 应用二、派件给对应的人(通过抽象类注册)
public abstract class AbstractNodeCodeObserver implements NodeObserver {//这个抽象类的作用是帮助子类注册作为观察者,子类无需在重复定义 @Overridepublic void afterPropertiesSet() throws Exception {NodeCodeManager.register(this);}
}@Service
public class AssigneeNodeObserver extends AbstractNodeCodeObserver {@Overridepublic List<String> registerCode() {return Arrays.asList("vrf","evl","visit");}@Overridepublic void nodeChange(NodeInfo nodeInfo) {System.out.println("案件:caseId:"+nodeInfo.getCaseId()+"开始派件:"+nodeInfo.getNodeCode());}}#测试,使用spring环境@SpringBootTest
class SpbootApplicationTests {@Resourceprivate AssigneeNodeObserver assigneeNodeObserver;@Testpublic void notifyAllTest() {NodeInfo nodeInfo = new NodeInfo();nodeInfo.setCaseId(1L);nodeInfo.setNodeCode("vrf");NodeCodeManager.notifyAll(nodeInfo);}}
设计模式之适配器模式、委派模式、访问者模式、工厂模式、桥接模式(双维度扩展)相关推荐
- VMware虚拟机三种网络模式详解--Bridged(桥接模式)
VMware虚拟机三种网络模式详解--Bridged(桥接模式) 简介: 由于Linux目前很热门,越来越多的人在学习Linux,但是买一台服务器放家里来学习,实在是很浪费. 那么如何解决这个问题?虚 ...
- VMWare三种工作模式详解,bridged(桥接模式)、NAT(网络地址转换模式)和host-only(主机模式)。
--------------------- 作者:CleverCode 来源:CSDN 原文:https://blog.csdn.net/CleverCode/article/details/4 ...
- 2021-08-03 VMware虚拟机三种网络模式详解 Bridged(桥接模式)
VMware虚拟机三种网络模式详解 Bridged(桥接模式) 参考连接:VMware虚拟机三种网络模式详解 Bridged(桥接模式)
- 虚拟机(VMware Workstation)中,把连接网络的模式由“NAT模式”,改成“自动桥接模式”,网速大大的提升...
安装虚拟机,默认情况下,联网的模式是NAT,即跟主机是转发共用网络资源的,这样就非常慢,时常网页都打不开,现把它改成桥接模式,让它独立成为一台物理机,网速有大大的改善,设置操作如下: VM --> ...
- VMware虚拟机三种网络模式详解 Bridged(桥接模式)
原文地址:http://www.linuxidc.com/Linux/2016-09/135521.htm 由于Linux目前很热门,越来越多的人在学习Linux,但是买一台服务放家里来学习,实在是很 ...
- Java设计模式(建造者模式-适配器模式-桥接模式)
Java设计模式Ⅲ 1.建造者模式 1.1 建造者模式概述 1.2 建造者模式的注意事项和细节 1.3 代码理解 2.适配器模式 2.1 类适配器模式 2.1.1 代码理解 2.2 对象适配器模式 2 ...
- 设计模式GOF23之-------------------结构型模式(适配器模式、代理模式、桥接模式、装饰模式、组合模式、外观模式、享元模式)
一 结构型模式 二 适配器模式 下面我将用代码模拟键盘usb接口和ps/2的转接器 的适配器过程: 首先定义客户需求: package GOF23;public interface Target {v ...
- Java设计模式(四):结构性模式(适配器模式、桥接模式、装饰模式、组合模式、外观模式、亨元模式、代理模式)
目录 一· 适配器设计模式 1.1 现实生活中的适配器例子 1.2 基本介绍 1.3 工作原理 1.4 类适配器模式 1.5 对象适配器模式 1.6 接口适配器模式 1.7 适配器模式在 Spring ...
- 《深入设计模式》笔记 -创建型模式二、工厂方法模式
抽象工厂模式 亦称: Abstract Factory 意图 抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类. 问题 假设你正在开发一款家具商店模拟器. 你的代码中 ...
最新文章
- sudo找不到命令:修改sudo的PATH路径
- python打开一个文件-python,一读取文件open()
- ubuntu c++ 实现自动回车键功能_特斯拉已实现完全自动驾驶功能?是噱头还是技术的突破?...
- 程序员必知--代码规范
- 数据库每日一题(易错)
- 如何打造程序员专属聊天室?
- day12(html、css)
- [tensorflow]tensorflow 顺序模型(Sequential model)
- 机器学习实战(2)—— k-近邻算法
- Java继承中的覆盖
- 用C语言能编程工控机吗,工控机、PLC、单片机的区别 工控机应用于哪些领域
- li指令 汇编_汇编语言和汇编软件
- 给JavaScript 初心者的ES2015 实战
- Mybatis-Plus 传入时间查询的方式
- 项目管理学习总结(15)——技术负责人所需的四个核心能力
- 计算机组成与体系结构 LRU 算法与 MRU 算法对比
- BABvsBABAB
- CodeForces 518A Vitaly and Strings
- 初识Struts2框架
- MATLAB与STK互联28:仿真案例3—读取轨道六根数(DataProviders使用示例)