Java架构师都有哪些要求
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java架构师都有哪些要求相关的知识,希望对你有一定的参考价值。
什么是架构?什么是架构师?Java架构师和工程师有何区别?这似乎是聊架构话题时永恒的问题。
因为从实际情况看,在不同的系统层级,不同的需求下架构师的职责也会不同;从不同的技术角度看,架构师又是个变色龙,一时是技术的大拿,一时是技术的规划者,一时是技术团队的指挥者。
那么,该如何回答“什么是架构,什么是架构师”这个问题呢?这或许需要先搞清楚另外一个问题——一名程序员是如何走上架构师之路的?通过很多实际案例,可以看出,程序员走上架构师之路,总结起来最多的原因是因为他早前代码写的好。
那么,代码写的好就是架构吗?显然不是。代码写的好只是表象,做所有事情都需要规划,尤其是一个复杂的软件系统,这更需要规划,否则可能连一行代码都写不出。复杂的软件系统一定会需要做很多抽象设计、对象规划、接口规划等准备动作。也就是“传统老一辈儿程序员”口中所说的:详细设计。做架构主要的事情也依旧如此,需要对整个系统进行系统的规划:模块、通讯、边界、扩展、技术下沉等工作。这样的规划完成之后项目方能正常跑起来。
当然,架构也不仅仅是规划,还要做的另一件大事就是技术识别。识别出系统中技术的难易区域,并分解复杂技术,使之成为一个个技术的黑盒子,在此之上再进行新的技术规划,使整个系统从技术角度来看是分层次的,从难到易,从大到小,但各层之间又是互相的黑盒。这也常说的让系统模块间达到“鸡犬相闻老死不相往来“的状态。
一个架构师需要足够的技术的宽度。从软件到硬件,从开发到测试,从运维到安全等都需要面面俱到的了解。当然你可能不是这单方面领域里面最深入的人,但是你需要知道它们是怎么做的(不仅仅是皮毛,要深入原理),并且要知道它们组合起来是个什么样的东西。技术面也足够宽了之后,是不是就会成为完美架构师呢?
答案是不会,因为还有新的问题要过来。这次的问题诸如“系统在未来的运行过程中运维需要做什么?”“系统在未来的功能迭代中如何更方便的扩展?”“系统应该怎么修改?”“系统应该被怎么样升级?”这时的你是不时很困惑?是不是感觉这个架构的世界好长啊,怎么像保姆一样什么都要管。但仔细想想这是应该的,因为一个系统初次开发并交付只是它生命周期中的一小部分而已。后面的维护、改造、升级才占了整个软件生命周期的绝大部分时间。你是它的架构设计者,是它灵魂之所在,你当然应该设计好它的未来。这也是架构师做好的最后一件事情:系统未来的设计。
架构师的定义?
个人觉得架构师需要具有以下几特点:
知识广度:需要知道主流技术为什么诞生,能解决什么问题?如果同一种业务用不用的技术来实现,会有什么哪些优缺点?比如:流行的ORM框架Mybatis 和 hibernate ,他们之间的优缺点是什么?要有清晰的认识会能在技术造型时做出正确的决定。
抽象能力:对业务和技术进行抽象。业务抽象就是对需求进行分析后,能够建立完美的实体类以及他们之间的联系。技术抽象是对整体架构进行一个分层,各层之间的交互。这至关重要,如果技术抽象能力不足,这会导致整个系统的架构不灵活,难以维护和扩展。
知识的深度:至少是某个领域的专家,比如消息队列,activeMQ熟悉其源码,知道其实现。
优秀的学习能力:对新的技术和前沿性的技术进行学习,使用它来解决工作中的业务问题。
那么你该如何去做呢?我觉得可以从以下几个步骤开始:
1: 扎实的JAVA 基础,Think in java上介绍的内容都能理解,做到这一步恭喜成为了程序员。
2:熟练使用主流框架,如:mybatis,spring 等。
3:研究过至少一种以web框架的源码,如spring mvc ,struts 等。
4:架构过或者参与过高并发系统设计,知道如何应对突发情况。
5:对自己所处的业务能够根据自己的知识维度,提出优化建议或者预测其风险点。
6:如果想看书籍可以看看这里做的介绍:
Java架构师之路:推荐的15本书?www.zhihu.com
其实能否成为架构师跟机遇有很大关系,比如一个程序员,以上都做到了,但是公司并没有给他这个机会去做,一个真正架构的机会。因为之前的架构师不离职他就没有机会,这就是现实!
参考技术A JAVA架构师要求
原文:https://www.zhihu.com/question
专业素质要求:
1、理解架构师的职责和架构设计的目标、原则及取舍;
2、精通架构模式,Transaction、Security、Persistence等机制及实现,IOC、AOP、SOA等理念及实现;
3、精通Transaction、Security、Persistence等机制及实现,IOC、AOP、SOA等理念及实现;
4、精通面向对象技术、设计模式、OOAD、UML等技术;
5、精通各种主流应用架构和平台,熟悉工作流引擎、规则引擎等中间件等;
6、深入理解Spring、iBATIS、Hibernate、Struts、Webwork、JSF和Tapestry等框架的设计思想和实现方式,精通J2EE、XML、WebService、分布式、多线程等高性能架构相关开发技术;
7、精通主要应用服务器(Weblogic/WebSphere/Tomcat等)的配置和使用,熟悉Linux操作系统;
8、了解Web应用的性能瓶颈和调优方式;
9、熟练掌握Oracle/DB2/SQLServer数据库,至少熟悉其中一种数据库优化与数据挖掘技术;
10、良好的沟通协调能力,团队合作精神和执行力,思路开阔,积极上进,不断学习;
11、有银行业呼叫中心产品研发经验者优先;
12、有J2EE大型项目架构设计经验者优先;
13、有J2EE架构产品研发经验者优先;
14、通过SCEA认证者优先;
职位描述:
1、负责公司软件产品的技术选型、架构搭建;
2、负责设计和搭建软件开发项目系统架构(平台、数据库、接口和应用架构等),解决开发中各种系统架构问题;
3、负责软件系统平台核心功能模块设计、核心代码开发;
4、负责技术解决方案的编制工作,并能够将解决方案清晰的传达给客户和项目组成员;
5. 负责组织技术架构、解决方案的评审;
6. 主导项目关键技术问题的攻关,协助项目管理对技术问题进行跟;
7、对开发团队进行技术指导和培训;
为啥大多数系统架构师都坚持首先对接口进行编程?
【中文标题】为啥大多数系统架构师都坚持首先对接口进行编程?【英文标题】:Why do most system architects insist on first programming to an interface?为什么大多数系统架构师都坚持首先对接口进行编程? 【发布时间】:2010-09-08 02:18:13 【问题描述】:我读过的几乎每一本 Java 书籍都谈到了使用接口作为在对象之间共享状态和行为的一种方式,这些对象在第一次“构造”时似乎并不共享关系。
但是,每当我看到架构师设计应用程序时,他们做的第一件事就是开始对接口进行编程。怎么会?您如何知道将在该接口中发生的对象之间的所有关系?如果您已经知道这些关系,那为什么不直接扩展一个抽象类呢?
【问题讨论】:
【参考方案1】:对接口编程意味着尊重使用该接口创建的“合同”。因此,如果您的IPoweredByMotor
接口具有start()
方法,那么实现该接口的未来类,无论是MotorizedWheelChair
、Automobile
还是SmoothieMaker
,在实现该接口的方法时,都会为您的系统增加灵活性,因为一段代码可以启动许多不同类型事物的马达,因为这一段代码只需要知道它们对start()
的响应。他们如何开始并不重要,只是他们必须开始。
【讨论】:
值得指出的是,接口不是合约。合同是行为规范:组件 x 保证它将在场景 z 中执行 y。接口什么都不保证。要获得与验证行为耦合的接口的描述,就必须使用类。 这是一个虚拟合约。就像大多数雇佣合同(不幸的是,还有其他一些合同)一样,您可以选择遵守它或将其视为点火器。 @Scott:我会说接口就是合约。不是技术意义上的(即除了接口中提到的所有方法的存在之外,编译器不会强制执行合同)。但是一个接口需要每个方法的描述才算完整,这个描述代表了契约 它可能在某种意义上增加了灵活性,但在另一种意义上也增加了刚性:如果您后来发现您的抽象是错误的,界面将渗透到项目的每个角落;你完蛋了。【参考方案2】:这是推广松散coupling的一种方式。
在低耦合的情况下,一个模块的更改将不需要更改另一个模块的实现。
这个概念的一个很好的用法是Abstract Factory pattern。在 Wikipedia 示例中,GUIFactory 接口生成 Button 接口。具体的工厂可能是 WinFactory(生产 WinButton)或 OSXFactory(生产 OSXButton)。想象一下,如果您正在编写一个 GUI 应用程序,并且您必须查看 OldButton
类的所有实例并将它们更改为 WinButton
。那么明年,你需要添加OSXButton
版本。
【讨论】:
【参考方案3】:我认为抽象类在很大程度上被开发人员抛弃的原因之一可能是一种误解。
当Gang of Four写道:
编程到接口而不是实现。
没有 java 或 C# 接口之类的东西。他们谈论的是每个类都有的面向对象的接口概念。 Erich Gamma 在this interview 中提到了它。
我认为不加思索地机械地遵循所有规则和原则会导致难以阅读、导航、理解和维护代码库。记住:最简单的事情可能会奏效。
【讨论】:
【参考方案4】:我会假设(使用@eed3s9n)这是为了促进松散耦合。此外,如果没有接口,单元测试会变得更加困难,因为您无法模拟您的对象。
【讨论】:
【参考方案5】:从某种意义上说,我认为您的问题可以归结为“为什么要使用接口而不是抽象类?”从技术上讲,你可以实现两者的松耦合——底层实现仍然没有暴露给调用代码,你可以使用抽象工厂模式返回一个底层实现(接口实现与抽象类扩展)来增加你的灵活性设计。事实上,您可能会争辩说抽象类给了您更多,因为它们允许您既需要实现来满足您的代码(“您必须实现 start()”)并提供默认实现(“我有一个标准的 paint()如果你愿意,可以覆盖") -- 对于接口,必须提供实现,随着时间的推移,这可能会通过接口更改导致脆弱的继承问题。
不过,从根本上说,我使用接口主要是因为 Java 的单一继承限制。如果我的实现必须从一个抽象类继承以供调用代码使用,这意味着我失去了从其他东西继承的灵活性,即使这可能更有意义(例如,对于代码重用或对象层次结构)。
【讨论】:
【参考方案6】:对接口进行编程有几个好处:
GoF 类型模式所必需,例如访客模式
允许替代实现。例如,对于抽象使用的数据库引擎的单个接口,可能存在多个数据访问对象实现(AccountDaoMySQL 和 AccountDaoOracle 都可能实现 AccountDao)
一个类可以实现多个接口。 Java 不允许具体类的多重继承。
抽象实现细节。接口可能只包含公共 API 方法,隐藏实现细节。好处包括文档清晰的公共 API 和文档完善的合同。
被现代依赖注入框架大量使用,例如http://www.springframework.org/。
在 Java 中,接口可用于创建动态代理 - http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/Proxy.html。这可以非常有效地与 Spring 等框架一起使用,以执行面向方面的编程。方面可以向类添加非常有用的功能,而无需直接向这些类添加 java 代码。此功能的示例包括日志记录、审计、性能监控、事务划分等。http://static.springframework.org/spring/docs/2.5.x/reference/aop.html。
模拟实现、单元测试 - 当依赖类是接口的实现时,可以编写模拟类来实现这些接口。模拟类可用于促进单元测试。
【讨论】:
实现访问者模式不需要接口。【参考方案7】:很好的问题。我会把你推荐给Josh Bloch in Effective Java,他写了(第 16 条)为什么更喜欢使用接口而不是抽象类。顺便说一句,如果你还没有这本书,我强烈推荐它!以下是他所说的摘要:
-
可以轻松改造现有类以实现新接口。您需要做的就是实现接口并添加所需的方法。现有的类不能轻易改造以扩展新的抽象类。
接口是定义混入的理想选择。混入接口允许类声明额外的可选行为(例如,Comparable)。它允许将可选功能与主要功能混合。抽象类不能定义混合——一个类不能扩展多个父类。
接口允许使用非分层框架。如果您的类具有许多接口的功能,则它可以实现所有接口。如果没有接口,您将不得不为每个属性组合创建一个带有类的臃肿类层次结构,从而导致组合爆炸。
接口可以增强安全功能。您可以使用 Decorator 模式创建包装类,这是一种强大而灵活的设计。包装类实现并包含相同的接口,将一些功能转发给现有方法,同时将特殊行为添加到其他方法。你不能用抽象方法来做到这一点 - 你必须使用继承,这更脆弱。
抽象类提供基本实现的优势是什么?您可以为每个接口提供一个抽象的骨架实现类。这结合了接口和抽象类的优点。骨架实现提供了实现帮助,而不会强加抽象类在用作类型定义时所强制的严格约束。例如,Collections Framework 使用接口定义类型,并为每个接口提供一个框架实现。
【讨论】:
【参考方案8】:在我看来,您经常看到这种情况,因为这是一种非常好的做法,但经常被应用在错误的情况下。
接口相对于抽象类有很多优点:
您可以切换实现,而无需重新构建依赖于接口的代码。这对于:代理类、依赖注入、AOP 等很有用。 您可以在代码中将 API 与实现分开。这可能很好,因为当您更改会影响其他模块的代码时,它会很明显。 它允许开发人员编写依赖于您的代码的代码,以便轻松地模拟您的 API 以进行测试。在处理代码模块时,您可以从接口中获得最大的优势。但是,没有简单的规则来确定模块边界应该在哪里。因此,这种最佳实践很容易被过度使用,尤其是在首次设计某些软件时。
【讨论】:
【参考方案9】:怎么会?
因为所有的书都是这么说的。与 GoF 模式一样,许多人认为它普遍适用,从不考虑它是否真的是正确的设计。
您如何知道将在该界面中发生的所有对象之间的关系?
你没有,这是个问题。
如果 你已经知道这些关系, 那么为什么不只是扩展一个摘要 上课?
不扩展抽象类的原因:
-
您的实现完全不同,制作一个体面的基类太难了。
你需要烧掉你唯一的基类来做别的事情。
如果两者都不适用,请继续使用抽象类。这将为您节省大量时间。
你没有问的问题:
使用界面有什么缺点?
您无法更改它们。与抽象类不同,接口是一成不变的。一旦你有一个在使用,扩展它会破坏代码,句号。
我真的需要吗?
大多数时候,没有。在构建任何对象层次结构之前,请认真思考。像 Java 这样的语言的一个大问题是它太容易创建大量复杂的对象层次结构。
考虑 LameDuck 继承自 Duck 的经典示例。听起来很简单,不是吗?
嗯,直到你需要表明鸭子已经受伤并且现在是瘸腿的。或表示瘸腿鸭已经痊愈,可以再次行走。 Java 不允许您更改对象类型,因此使用子类型来指示跛行实际上不起作用。
【讨论】:
【参考方案10】:一个原因是接口允许增长和可扩展性。例如,假设您有一个将对象作为参数的方法,
公共无效饮料(咖啡 someDrink)
现在假设您想使用完全相同的方法,但传递一个 hotTea 对象。好吧,你不能。您只是将上述方法硬编码为仅使用咖啡对象。也许那是好的,也许那是坏的。上述方法的缺点是,当您想传递各种相关对象时,它会将您严格锁定在一种类型的对象中。
通过使用接口,比如 IHotDrink,
接口 IHotDrink
并重写您的上述方法以使用接口而不是对象,
公共无效饮料(IHotDrink someDrink)
现在您可以传递所有实现 IHotDrink 接口的对象。当然,您可以编写完全相同的方法,用不同的对象参数执行完全相同的操作,但为什么呢?你突然维护臃肿的代码。
【讨论】:
【参考方案11】:Why extends is evil。这篇文章几乎是对所提问题的直接回答。我几乎想不出你真的需要一个抽象类的情况,而且在很多情况下这是个坏主意。这并不意味着使用抽象类的实现不好,但是您必须注意不要让接口契约依赖于某些特定实现的工件(例如:Java 中的 Stack 类)。
还有一件事:没有必要,也没有好的做法,到处都有接口。通常,您应该确定何时需要接口,何时不需要。在理想的世界中,第二种情况大部分时间都应该作为最终类来实现。
【讨论】:
【参考方案12】:对接口进行编程意味着尊重由 使用那个界面
这是关于接口的最容易被误解的事情。
没有办法通过接口强制执行任何此类合同。根据定义,接口根本不能指定任何行为。类是行为发生的地方。
这种错误的信念是如此普遍,以至于被许多人认为是传统智慧。然而,这是错误的。
所以OP中的这个语句
我读过的几乎每一本 Java 书籍都谈到了使用接口作为一种方式 在对象之间共享状态和行为
是不可能的。接口既没有状态也没有行为。他们可以定义实现类必须提供的属性,但这是尽可能接近的。您不能使用接口共享行为。
您可以假设人们将实现一个接口以提供其方法名称所暗示的那种行为,但这不是一回事。并且它对何时调用此类方法没有任何限制(例如,应在 Stop 之前调用 Start)。
此声明
GoF 类型模式所必需,例如访问者模式
也不正确。 GoF 书完全使用零接口,因为它们不是当时使用的语言的特性。没有一种模式需要接口,尽管有些模式可以使用它们。 IMO,观察者模式是一种接口可以扮演更优雅角色的模式(尽管现在该模式通常使用事件来实现)。在访问者模式中,几乎总是需要一个基本访问者类来实现每种类型的访问节点的默认行为,即 IME。
我个人认为这个问题的答案有三个:
接口被许多人视为灵丹妙药(这些人通常在“合同”误解下工作,或者认为接口神奇地解耦了他们的代码)
Java 人非常注重使用框架,其中许多(正确地)需要类来实现其接口
在引入泛型和注释(C# 中的属性)之前,接口是做某些事情的最佳方式。
接口是一个非常有用的语言特性,但被滥用了很多。症状包括:
一个接口只能由一个类实现
一个类实现多个接口。通常被吹捧为接口的一个优点,通常这意味着所讨论的类违反了关注点分离的原则。
接口有一个继承层次结构(通常由类层次结构反映)。这是您首先要通过使用接口来避免的情况。对于类和接口来说,过多的继承是一件坏事。
所有这些都是代码异味,IMO。
【讨论】:
【参考方案13】:一切都是在编码之前进行设计。
如果您在指定接口后不知道两个对象之间的所有关系,那么您在定义接口方面做得很差——这相对容易修复。
如果您直接潜入编码并在中途意识到您遗漏了一些东西,那么您将很难修复。
【讨论】:
【参考方案14】:这里有一些很好的答案,但如果你正在寻找一个具体的原因,那就看看单元测试吧。
假设您想在业务逻辑中测试一个方法,该方法检索交易发生区域的当前税率。为此,业务逻辑类必须通过 Repository 与数据库对话:
interface IRepository<T> T Get(string key);
class TaxRateRepository : IRepository<TaxRate>
protected internal TaxRateRepository()
public TaxRate Get(string key)
// retrieve an TaxRate (obj) from database
return obj;
在整个代码中,使用类型 IRepository 而不是 TaxRateRepository。
仓库有一个非公开的构造函数来鼓励用户(开发者)使用工厂来实例化仓库:
public static class RepositoryFactory
public RepositoryFactory()
TaxRateRepository = new TaxRateRepository();
public static IRepository TaxRateRepository get; protected set;
public static void SetTaxRateRepository(IRepository rep)
TaxRateRepository = rep;
工厂是唯一直接引用 TaxRateRepository 类的地方。
所以你需要一些支持这个例子的类:
class TaxRate
public string Region get; protected set;
decimal Rate get; protected set;
static class Business
static decimal GetRate(string region)
var taxRate = RepositoryFactory.TaxRateRepository.Get(region);
return taxRate.Rate;
还有另一个 IRepository 的其他实现 - 模型:
class MockTaxRateRepository : IRepository<TaxRate>
public TaxRate ReturnValue get; set;
public bool GetWasCalled get; protected set;
public string KeyParamValue get; protected set;
public TaxRate Get(string key)
GetWasCalled = true;
KeyParamValue = key;
return ReturnValue;
因为实时代码(业务类)使用工厂来获取存储库,所以在单元测试中,您为 TaxRateRepository 插入 MockRepository。替换完成后,您可以硬编码返回值并使数据库变得不必要。
class MyUnitTestFixture
var rep = new MockTaxRateRepository();
[FixtureSetup]
void ConfigureFixture()
RepositoryFactory.SetTaxRateRepository(rep);
[Test]
void Test()
var region = "NY.NY.Manhattan";
var rate = 8.5m;
rep.ReturnValue = new TaxRate Rate = rate ;
var r = Business.GetRate(region);
Assert.IsNotNull(r);
Assert.IsTrue(rep.GetWasCalled);
Assert.AreEqual(region, rep.KeyParamValue);
Assert.AreEqual(r.Rate, rate);
请记住,您只想测试业务逻辑方法,而不是存储库、数据库、连接字符串等……每个测试都有不同的测试。通过这样做,您可以完全隔离您正在测试的代码。
另一个好处是,您也可以在没有数据库连接的情况下运行单元测试,这使得它更快、更便携(想想远程位置的多开发团队)。
另一个好处是您可以在开发的实施阶段使用测试驱动开发 (TDD) 流程。我不严格使用 TDD,而是混合使用 TDD 和老式编码。
【讨论】:
【参考方案15】:您可以从 perl/python/ruby 的角度看到这一点:
当您将对象作为参数传递给方法时,您没有传递它的类型,您只知道它必须响应某些方法我认为将 java 接口作为类比最能解释这一点。你并没有真正传递一个类型,你只是传递一个响应方法的东西(如果你愿意的话,一个特征)。
【讨论】:
【参考方案16】:我认为在 Java 中使用接口的主要原因是对单继承的限制。在许多情况下,这会导致不必要的复杂性和代码重复。看看 Scala 中的 Traits:http://www.scala-lang.org/node/126 Traits 是一种特殊的抽象类,但一个类可以扩展其中的许多。
【讨论】:
以上是关于Java架构师都有哪些要求的主要内容,如果未能解决你的问题,请参考以下文章
java高级架构师进阶路线,年薪百万的架构师都是按照这个路线学习的