当前位置: 首页 > news >正文

大学生创业 2月亏3万搜索引擎优化面对哪些困境

大学生创业 2月亏3万,搜索引擎优化面对哪些困境,网站动态背景欣赏,怎样用ps做网站的效果图一、前言 有时候不想动脑子,就懒得看源码又不像浪费时间所以会看看书,但是又记不住,所以决定开始写"抄书"系列。本系列大部分内容都是来源于《 图解设计模式》(【日】结城浩 著)。该系列文章可随意转载。 …

一、前言

有时候不想动脑子,就懒得看源码又不像浪费时间所以会看看书,但是又记不住,所以决定开始写"抄书"系列。本系列大部分内容都是来源于《 图解设计模式》(【日】结城浩 著)。该系列文章可随意转载。

二、Bridge 模式

Bridge 模式 :将类的功能层析结构与实现层次结构分离。

1. 介绍

Bridge 模式的作用是将两种东西连接起来,它们分别是 类的功能层次结构 和 类的实现层次结构,但是通常来说,类的层次结构不应当过深。

  • 类的功能层次结构 :在父类中具有基本功能,在子类中增加新的功能。这种层次结构成为 类的功能层次结构。
  • 类的实现层次结构:父类通过声明抽象方法来定义接口,子类通过实现具体方法来实现接口。这种层次结构称为 类的实现层次结构。

Bridge 模式登场的角色

  • Abstraction (抽象化) : 该角色位于“类的功能层次结构”的最上层,他使用 Implementor 角色的方法定义了基本的功能。该角色保存了 Implementor 角色的实例。在示例程序中,由 Display 类扮演此角色。
  • RefineAbstraction (改善后的抽象化) :在 Abstraction 角色的基础上增加了新功能的角色。在示例程序中,由 CountDisplay 类扮演此角色。
  • Implementor (实现者) :该角色位于“类的实现层次结构”的最上层,他定义了用于实现 Abstraction 角色的接口的方法。在示例程序中由 DisplayImple 类扮演此角色。
  • ConcreteImplementor (具体实现者) :该角色负责实现在 Implementor 角色中定义的接口(API)。在实例程序中,由 StringDisplayImple 类扮演该角色。

类图如下,左侧的两个类构成了“类的功能层次结构”,右侧的两个类构成了“类的实现层次结构”。类的两个层次结构之间的桥梁是 impl 字段:
在这里插入图片描述


Demo 如下:

// 类的功能层次结构
public class Display {private DisplayImpl impl;public Display(DisplayImpl impl) {this.impl = impl;}public void open() {impl.rawOpen();}public void print() {impl.rawPrint();}public void close() {impl.rawClose();}
}
// 类的实现层次结构
public interface DisplayImpl {void rawOpen();void rawPrint();void rawClose();
}// 类的实现层次结构
public class StringDisplayImpl implements DisplayImpl {@Overridepublic void rawOpen() {System.out.println("StringDisplayImpl.rawOpen");}@Overridepublic void rawPrint() {System.out.println("StringDisplayImpl.rawPrint");}@Overridepublic void rawClose() {System.out.println("StringDisplayImpl.rawClose");}
}// 类的功能层次结构
public class CountDisplay extends Display {public CountDisplay(DisplayImpl impl) {super(impl);}public void multiDisplay() {for (int i = 0; i < 3; i++) {print();}}
}public class BridgeDemoMain {public static void main(String[] args) {Display display1 = new Display(new StringDisplayImpl());Display display2 = new CountDisplay(new StringDisplayImpl());display1.display();System.out.println("--------------------------------");display2.display();System.out.println("--------------------------------");((CountDisplay)display2).multiDisplay();}
}

输出结果:

在这里插入图片描述
综上:通过 CountDisplay 类完成了对 Display 类的方法扩展,即类的功能层次结构扩展。通过 DisplayImpl 类完成了与 Display 的解耦,Display 将 open、print、close 方法委托给了 impl 来实现,即类的实现层次结构扩展。

2. 应用

  • Spring 中的 BeanPostProcessor 接口:在 Spring 中 Bean 创建前后会调用 BeanPostProcessor 的方法来对 Bean进行前置或后置处理,而 BeanPostProcessor 具有很多子接口,如 InstantiationAwareBeanPostProcessor 、MergedBeanDefinitionPostProcessor 等,其子接口都各自增加了自己的方法。如下接口定义:

    public interface BeanPostProcessor {@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}}public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {@Nullabledefault Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {return null;}default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true;}@Nullabledefault PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)throws BeansException {return null;}@Deprecated@Nullabledefault PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {return pvs;}}
    


个人使用:该部分内容是写给自己看的,帮助自身理解,因此就不交代项目背景了,读者请自行忽略(◐ˍ◑)

  • 项目A中需要对文件进行解析,当时为了兼容各种文件,定义了文件解析委托类,并且在此基础上进行了扩展,如下,不同的文件类型基于自身的特性实现不同的接口来完成基础功能的解析:

    // 接口, 文件解析委托类
    public interface DocDelegate extends Closeable {/*** 读取全部内容** @return*/<K> K readContent();/*** 关闭** @throws IOException*/@Overridedefault void close() {}
    }// 用于解析可以按行读取的文件,如 Excel
    public interface DocLineDelegate<T> extends DocDelegate {/*** 按行分割 内容** @return*/List<T> readLineContent();}// 用于解析可以按页读取的文件,如Word
    public interface DocPageDelegate<T> extends DocDelegate {/*** 获取当前页数** @return*/int getNumberOfPages();/*** 读取某一页的内容** @param page* @return*/T readPage(int page);}
    

3. 总结

Bridge 模式的特征是将“类的功能层次结构” 和“类的实现层次结构”分离开了。当想要增加功能时,只需要在“类的功能层次结构” 一侧增加类即可。不必对“类的实现层次结构”做任何修改,而且增加够的功能可以被“所有的实现”使用。

需要注意的是,虽然使用“继承”也很容易扩展类,但是类之前形成了一种强关联关系,如果需要修改类之前的关系,使用继承就不合适了,因为每次改变都需要修改原程序。这是便可以使用"委托"来代替“继承关系”。如上述Demo中,Display 将 open、print、close 方法委托给了 impl 来实现,如果需要改变关联关系,在创建 Display 时传入新的 Impl 实现即可。

三、Strategy 模式

Strategy 模式 : 整体地替换算法

1. 介绍

Strategy 模式登场的角色:

  • Strategy (策略):Strategy 角色负责决定实现策略所必需的接口(API)。
  • ConcreteStrategy(具体的策略):ConcreteStrategy角色负责实现 Strategy 角色的接口,即负责实现具体的策略。
  • Context(上下文):负责使用Strategy 角色。Context 角色保存了 ConcreteStrategy 角色的实例,并使用ConcreteStrategy 角色去实现需求。

类图如下:
在这里插入图片描述


Demo如下:

// 策略接口
public interface Strategy {int getNumber();
}// 获取随机奇数
public class OddNumberStrategy implements Strategy {@Overridepublic int getNumber() {int number;do {number = RandomUtils.nextInt();} while (number % 2 == 0);return number;}
}// 获取随机偶数
public class EvenNumberStrategy implements Strategy {@Overridepublic int getNumber() {int number;do {number = RandomUtils.nextInt();} while (number % 2 != 0);return number;}
}
//策略上下文,持有所有策略
public class StrategyContext {private EvenNumberStrategy evenNumberStrategy = new EvenNumberStrategy();private OddNumberStrategy oddNumberStrategy = new OddNumberStrategy();public int getEventNumber(){return evenNumberStrategy.getNumber();}  public int getOddNumber(){return oddNumberStrategy.getNumber();}
}public class StrategyDemoMain {public static void main(String[] args) {// 选择合适的策略执行StrategyContext strategyContext = new StrategyContext();final int oddNumber = strategyContext.getOddNumber();final int eventNumber = strategyContext.getEventNumber();System.out.println("oddNumber = " + oddNumber);System.out.println("eventNumber = " + eventNumber);}
}

2. 应用

  • 线程池的任务拒绝策略:在我们自定义线程时是需要传入一个任务拒绝处理器,Java默认提供了多种拒绝策略的实现,通过选择不同的策略可以在线程池满任务时选择对应的处理方式,如丢失任务、抛出异常等。如下,可以通过传入不同的 RejectedExecutionHandler 来实现不同的拒绝策略。

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {if (corePoolSize < 0 ||maximumPoolSize <= 0 ||maximumPoolSize < corePoolSize ||keepAliveTime < 0)throw new IllegalArgumentException();if (workQueue == null || threadFactory == null || handler == null)throw new NullPointerException();this.corePoolSize = corePoolSize;this.maximumPoolSize = maximumPoolSize;this.workQueue = workQueue;this.keepAliveTime = unit.toNanos(keepAliveTime);this.threadFactory = threadFactory;this.handler = handler;
    }
  • Dubbo的负载均衡策略: Dubbo 通过 LoadBalance 接口完成负载均衡,而负载均衡有多种方案可以选择,如随机、轮询、按比重等等,Dubbo 对每种情况实现了各自的 LoadBalance ,然后根据配置选择合适的 LoadBalance 策略来完成负载均衡。

    	// AbstractLoadBalance 中,子类 LoadBalance 实现 doSelect 方法来实现自己的策略。@Overridepublic <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) {if (CollectionUtils.isEmpty(invokers)) {return null;}if (invokers.size() == 1) {return invokers.get(0);}return doSelect(invokers, url, invocation);}protected abstract <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation);
    


个人使用:该部分内容是写给自己看的,帮助自身理解,因此就不交代项目背景了,读者请自行忽略(◐ˍ◑)

  • 项目A 中需要对文件进行解析读取,对于同一份文件,在不同的用途时需要解析获取的数据也不同,此时会为每种目的建立不同的读取策略,通过不同的策略来获取不同的信息。

  • 项目B 中需要手动提供一个 TraceId 进行数据记录,对于这种情况肯定是通过AOP 完成,除此之外,为了普适性,额外提供了一个 TraceId 生成的策略类,如果某个项目需求不同,需要生成不同格式的 TraceId,则可以通过实现策略类来完成。如下:

    public interface TraceIdStrategy {/*** 获取 id** @return*/String getTraceId();/*** 获取id** @param traceId* @return*/String getTraceId(String traceId);
    }//提供一个默认的策略
    public class DefaultTraceIdStrategy implements TraceIdStrategy {@Overridepublic String getTraceId() {return UUID.randomUUID().toString();}@Overridepublic String getTraceId(String traceId) {return traceId;}
    }// 注入MDC 
    @Order(Integer.MIN_VALUE)
    public class MDCTraceConfigurer implements WebMvcConfigurer {private final TraceIdStrategy traceIdStrategy;public MDCTraceConfigurer(ObjectProvider<TraceIdStrategy> traceIdStrategyOp) {this.traceIdStrategy = traceIdStrategyOp.getIfAvailable(DefaultTraceIdStrategy::new);}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MDCTraceInterceptor(traceIdStrategy)).addPathPatterns("/**");}
    }
    

3. 总结

相关设计模式:

  • Flyweight 模式 :有时会使用Flyweight 模式让多个地方可以共用 ConcreteStrategy 角色。
  • Abstract Factory 模式 :使用 Strategy 模式可以整体替换算法,使用 Abstract Factory 模式则可以整体地替换具体工厂、零件和产品
  • State 模式:使用Strategy 模式和 State模式都可以替换被委托对象,而且他们的类之间的关系也很相似。但是这两种模式的目的不同。Strategy 模式中 ConcreteStrategy 角色是代表算法的类。在 Strategy 模式中,可以替换被委托的对类。而在 State模式中,ConcreteState 角色是表示 “状态” 的类。在 State模式中,每次状态变化时,被委托对象的类都必定会被替换掉。
http://www.sczhlp.com/news/123539/

相关文章:

  • 搜狐网站开发一级域名网站建设
  • 在家有电脑怎么做网站工程公司名字大全大气好听
  • 阿里 网站备案核验单正版win10做win7系统下载网站
  • 合肥建设工会网站怎样制作一个网页
  • 个体工商户可以搞网站建设摄影网站模板
  • Day24_【深度学习—广播机制】 - 详解
  • 网站开发前景怎么样yp77731域名查询
  • 做qq空间网站企业内部管理系统
  • 英雄联盟网站建设做seo的网站是怎么样的
  • 网站开发语言什么意思凡科互动自助解封没用
  • 长春有什么好的网站制作公司WordPress 三图
  • 网站怎么更改后台登陆密码比较流行的sns营销网站
  • 宁乡县住房和城乡建设局网站医院的网站建设目标
  • 网站设计专业实验室建设wordpress公司展示网站
  • 嘉兴网站建设多少时间做网站销售需要注意的
  • 女性做网站荣耀正品查询入口
  • wordpress登录密码重置密码天津优化网站哪家好用
  • 重庆九龙坡区网站建设横沥镇网站建设公司
  • 网站横幅广告代码网站建设新规
  • 长沙专业网站建设团队wordpress 首页不显示
  • 湖南做网站kaodezhu有自建服务器做网站的吗
  • 网站做优化的必要性网页制作和网页制作设计
  • 室内设计培训网站网站移动端优化工具
  • 别样的CSP-S初赛大战(又名:我和油一的那些年)
  • 在ubuntu系统的c语言程序
  • ucenter使用自己做的网站网站建设需要的人才
  • 购物网站asp源码网站建设原码
  • 网站未备案怎么做淘宝客广告优化师的工作内容
  • 建行信用卡网站php框架做网站
  • 南宁网站建设 南宁联达亿网站建设seo虾哥网络