|
September 2006
September 28, 2006
The Ultimate Answer
Yes! I've done it! I finally managed to discover the end all answer to all my (and your) architectural dilemmas.
Well, whatever architectural or design dilemma you're presented with and asked about, you can always answer "It depends." Okay, so it isn't that Earth shattering. You probably already knew this and, yes, you are right--this isn't the end-all answer :-). As it happens, however, it is true. It does depend. For most (if not all) design dilemmas, there is no "single" always correct answer. What seems like a crappy idea might be the best option under different time or budget constrains. A great Java-based solution might be useless for a team of VB 6 developers; going with the simplest thing that works might prove to be a waste of time if the next iteration requirements requirers more sophistication to be "implementable"; etc. etc.
This means a few things for us (as architects):
- Every decision is a trade-off. If something seems to be the "Ultimate answer" we should probably look again, see what other options we're missing, and think about the trade-offs and risks.
- There are no "best practices"--only "good practices" and a context where they fit (see, for example, my post on "simple 3-tier architectures". This is, by the way, why I like patterns so much. Patterns describe a specific problem, force making the problem complicated, a solution and consequences. This make knowledge published as patterns more usable (in my opinion) from most other ways.
- (Good) Large (ambitious) frameworks are hard to create because if you need to answer all possible possibility you will most likely be spreading the code too thin to be of value either that or you get a monster which is hard to maintain and develop.
Lastly, you shouldn't get too discouraged from the lack of best design decision codex. The good news are that all this spells job security for all of us, since someone will always have to make these decisions, and make the right ones for the context (if we are to produce a good product).
Posted by Arnon Rotem-Gal-Oz at 05:31 PM Permalink
|
September 26, 2006
On Using UML: Replies to Comments
A few posts ago I talked about using UML for communicating designs and architectures. This post has my replies to some of the comments.
I warned against using UML with non-technical people and someone (guest) said:
I have had excellent luck sharing some UML diagrams with non-technical people. For example, simple use case diagrams are a great way to show what the system(s) will do, and who is expected to interact with them. Business people of all stripes understand them immediately.
I am not saying don't use UML for non-technical people. I was merely pointing out that you should be aware that non-technical people might not understand them or even worse understand them differently.
Barry Mundi said:
What with articles around the place describing the dearth of use of UML, and my experience within the software engineering industry, I am not surprised people are asking questions like this. The whole opensource community seems to run sans modeling. Most developers have trouble understanding class and sequence diagrams, let alone the other classes of diagrams in UML. Often, if you see a class diagram it has been reversed engineered by a tool rather than the meat of cogitation. Little architectural representation is seen. Some of my colleagues and I are opposed to generally calling everyone a Software Engineer. Developers can't or won't model effectively, given either their imperatives or their bent -- or lack of it. What with Jacobbson's comments about "accidental architecture" being "ok" and the JVM now coming with behavioural journelling -- to allow accidental discovery of your software's purpose -- why do we bother with the pretence?
I don't think that not using UML = not doing design. UML is a good way to express design (esp. UML 2.x which is more expressive) but it isn't the only way and it isn't always the best option (e.g. what about layer
diagrams almost everyone uses, or BPM, business rules, UI etc.)
Regarding developers that can't model -- while not everybody is a good abstractionist, if I see anyone on my team who is completely incapable of doing design (TDD, formal model or otherwise) than he/she does not have a place in my team. I think the days of spoon feeding developers with detailed design documents were (or should have been) over years ago. People who are incapable of thinking about the consequences of the design/code they write will produce poor quality code.
Regarding "accidental architecture". I agree that this is wrong for anything but the most trivial projects. If you have "accidental architecture" don't be surprised when other accidents will happen to your code.
Another guest said:
...One of the main reasons that UML is becoming more attractive, especially to smaller companies, is not all because of a growing general awareness. It is because of the availability of much better and more affordable tools than what was available back then. I am certain you already got your hands of Enterprise Architect (SPARX), the phenom tool that is gaining grounds very rapidly because of its price to quality ratio -- check it out if you haven't.
To your point gentlemen, it's not only what you use UML for, but what you COULD use it for? There is a natural evolution in maturity that an organization can go through in order to move from 'charting pictures' to 'clear communication', then to 'UML for formal specification', then to using UML for expressing model patterns and metamodels (can't imagine doing that without a notation of any sort), and finally, mature to a model driven environment where you are generating much, much more, than just skeletal code.
The promise is there (we have seen it), what is needed is awareness.
Regarding Sparx Enterprise Architect -- this is definitely one of the best UML tools out there. I've been using it since version 4.5 and now with version 6.5 it is even better (by the way it goes beyond UML with diagrams for describing WSDLs or add-ons for SysML etc.). I finally managed to convince our System Engineering and Processes Group to switch everybody to EA over using (the dreadful) XDE.
Regarding the potential of UML for formal specification and MDA scenarios. I used to criticize Jack Greenfield and Keith Short for not basing their Software Factories Initiative on UML 2 (which is extensible) -- but thinking about it I do agree that there is no merit with sticking with UML over to going with DSLs since you would have to annotate (with tagged values and stereotypes) your model so much it would be much sensible to create a specific compact language.
By the way I think the so called "software factories" the patterns and practices group are producing these days are still very far from the vision of software factories that Jack and Kieth painted. The "real" factories are still very far away in my opinion.
Lastly, Duane Strong said:
You mention using the UML as sketch is not "fully compliant" UML. I'm not sure that is correct. To me compliant means that you are simply using UML in a way that complies with the rules of that language. This does in no way mean that you also have to fully document every detail of the model. In my experience deciding what to elide from the diagram is much more important that deciding what to leave in....
I did mean compliant in the sense of complying with the rules. If I would think that putting a port on a class would somehow make my diagram more clear to my audience I would do that. Also I wouldn't bother with the trouble of making sure code can be generated from the diagram.
I agree with you that there is no point in having diagrams that show each and every detail of the underlying code. The whole point of having the model in the first place is to raise the level of abstraction so that we have a better chance of understanding what is going on.
This is also a good opportunity to thank all of you who take the time to comment on my posts. It is nice to see someone out there actually reads this stuff :-). Also note that that the comments system on on this blog does not notify me when there's a new comment, so if you want to make sure I see your comment also copy my email (arnon@rgoarchitects.com )
Posted by Arnon Rotem-Gal-Oz at 04:22 PM Permalink
|
September 25, 2006
On Becoming a Software Architect: Round 2
In my previous post. I asked how many of you would be interested in hearing more tips/guidance for begining architects. Since I only got a few responses I would say the answer is "no"*. This means that apart from this post (and the previous one), I will not have posts that specifically targeting "newbie" architects (though I hope my other posts are relevant to you as well).
As a reminder, Ajay asked how do yo become an architect. Here is the reply I sent him:
I am not sure I can pin-point an exact route to becoming an architect. But maybe I can give you a few starting points. There are several pillars of what architect. There are some hard skills you can aquire: Technology depth and breadth, the ability to abstract and design.
On the soft-skills side (I blog on those here on Dr. Dobb's; see here is the first part) you can usually find courses for most of them (for example, I took courses on Strategic Planning, Negoiations and Conflict Resolution, Change Management (as in introducing change to an organization not source control), presentation skills, etc.). However, you need to practice to make the skills stick.
Another important factor is perspective--the more experience you get in various development roles the better architect you'd be. I think it is very helpful for an architect to see at least once project from inception to maintenance.
Some resources you can look at. Two good books are:
Some of the leading sites:
You might also find my architecture activities framework useful (I thought about creating a course but never got beyond syllabus outline and a couple of presentations).
A few other related sites:
Architecture Related Organizations :
Hope this helps you get started.
Arnon
* For those who did respond, you can send specific questions you have to ask@rgoarchitects.com and I'll try to help you out on my free time (or what's left of it).
Posted by Arnon Rotem-Gal-Oz at 07:42 AM Permalink
|
September 21, 2006
On Becoming a Software Architect
Another interesting question I recently received was from Ajay, a reader who said he was a developer aspiring to become an architect. Ajay wanted to know how he can go about becoming an architect.
To be truthful, I don't know of any orderly career path that can lead you to become an architect. You either get hired as one or one day you just declare yourself as one :-). However, there are probably a few things you can do if you want to be a good architect.
I can post the answer I send Ajay (probably I'll do that tomorrow), but before I do that there are a couple of things I want to discuss. The first thing is would any one be interested in few posts for new architects/aspiring architects (leave a comment or drop me an email arnon@rgoarchitects.com if you do)
The second issue is architect training. There isn't a lot of that happening. Dana Bredemeyer has a four-day workshop. (I've heard him present once and I've talked with a few people that went through the workshop and it seems pretty good). Again, I don't really know of anything else in this area.
I started to think about a 4-5 days workshop but never got to actually make it happen. This is what I had in mind:
- Part I: Architecture Basics
- Why
- What Software architecture
- Product Line Architecture
- Enterprise Architecture
- Introduction to software documentation
- Stakeholders
- Quality attributes
- Viewpoint
- Views
- Part II: The Architectural Process & context
- The SPAMMED process
- Architect vs. the World [The architect's place within the development organization]
- Project Management
- Requirements Management
- Design
- Development
- Testing
- Agile team
- Architect soft skills
- Part III: Architectural Topics
- Domain modeling and related trends (Software Factories/ MDA )
- Patterns/Styles
- Architectural Dilemmas [presenting an issue - open discussion and presenting some final thoughts]
- Topics like:
- O/R mapping vs, DAO
- Client side Thin vs. Smart vs. Web
- SOA
- Stateless vs. Stateful servers
- etc.
- Part IV: From Theory to Practice [this should be intertwined between the presentations]
- Problem Introduction
- Modeling
- Evaluation
While a workshop like this wouldn't make someone who isn't "ready" an architect, it would help those making their first steps into the field. Again, any comments are welcomed.
Posted by Arnon Rotem-Gal-Oz at 04:25 AM Permalink
|
September 19, 2006
On Using UML
A few days ago Silvia (one of this blog's readers) sent me a question regarding a (UML) deployment diagram she was working on. She wanted to know if the UML was good enough. I answered that it was good enough because it helped convey the point she was trying to make. (I also let her know about a couple of other UML features she can use to make it clearer, but that is besides the point.)
The interesting question this raises is what are you using UML for?
Most of the time I stick to the UML as a sketch camp. If you use UML in this mode it doesn't really matter if you are fully compliant with the UML spec as long as you can get your message across. UML is beneficial as many people are familiar with the notation. (As a side note I'd say that when presenting to non-developers UML can sometimes cause more confusion than help as the notation can seem cryptic to non technical people.)
We have development groups that use UML statecharts to general (real-time) parts of real-time systems. I guess that many (not all, maybe not even most) real-time systems have a relatively simple logic (what makes them complex is the dead-lines, jitter requirements etc.). In these scenarios you can create a state diagram to encompass all of the system's state (and these get real ugly, real fast as well). I can't imagine that happening for a CRM system, for example.
The point is that unless you are going to generate major parts of your application, I don't see a real reason to try to be fully compliant to the UML standard--because the benefit you get from that is rather low. I think that it is more important to use UML to express high-level decisions and design. Then, (if needed...) reverse engineer the code to get detailed design. if you are doing detailed design in UML you'd probably be much quicker coding it anyway.
There is a place for code generation using Domain Specific Languages (which, by the way, you can implement on top of UML 2.x) but this has a lot of other problems; see my post on Domain Specific Modeling.
P.S.
This is probably a good opportunity to remind you that you can send design/architecture questions you have to ask@rgoarchitects.com. While I don't promise I'll solve your problem, I will try to at least give some directions and if the issue is interesting to the general public, I'll post my view on the matter and try to answer on this blog.
Posted by Arnon Rotem-Gal-Oz at 02:19 AM Permalink
|
September 15, 2006
Frameworks and Agile Development
Scott Bellware writes about architects in agile teams.
In his blog, Scott also mentions building frameworks:
An agile architect also provides technical frameworks that keep the team in the intended groove -- and yes, this can even mean building frameworks in the course of an agile project -- as long as there's a customer-approved card for it, and as long as it's built micro-incrementally.
Why does it always seem that people who only do Agile development think the current project is rooted in vacuum? (Also see one of my previous posts.) What if you are writing project #3 which is very similar to the project #1 you did for another customer? What if project #4 which is in the pipeline is also similar. Once you've worked on several similar projects you can identify common "things" you can automate or write only once.
I am not saying that you should sit and theorize on what will be needed in future projects (far from it), but if your are building several projects in a row and you see that certain things that are worth moving into a framework -- do that. You don't need a customer card for that. And no, customers shouldn't pay for that (fund it from your R&D budget -- and if you don't have one, get one) since this, indeed, won't bring them any business value. (However it will bring you business value on your next engagement. It will also bring business value for your next customer as you would be able to save time by using code which is already tested and proven.
If there's a place for a technical framework within a project, then follow Scott's suggestion and get customer approval for that. In these cases the payoff would happen within the project.
By the way, Scott's main theme involves the responsibilities of architects on agile projects. I agree with what he says -- to an extent. One thing I don't agree with is that it has to do with agile projects. I think it has to do with project size. On smaller projects (e.g. 10 developers or less), there is no room for full-time architects. If architects are dedicated to the team (as would be the case in most if not all, agile projects) then they will need to have additional responsibilities (i.e. code as part of the team), if they are in charge of multiple project's or the project is large enough (e.g. 100+ man/years ) then she would probably not have the time to code. The same thing happens with "traditional" team leaders/project manager. If you are the team leader of a couple of developers, you will code with them. If you manage 50 people, you would hardly have any time for that (the difference, of course, that the architect should remain technical even on larger projects).
(I've written my views on "should architect's code" in the following series round 1, round 2, round 3. Also back in 2005 I mapped my SPAMMED framework to agile projects)
Posted by Arnon Rotem-Gal-Oz at 03:32 AM Permalink
|
September 13, 2006
The SPAMMED Architecture Framework
The October issue of the printed edition of Dr. Dobb's is out and among the many fine articles it has I manged to sneak in an article I wrote on the SPAMMED Architecture Framework (SAF).
SAF is a set of steps or activities I believe that an architect should perform (one way or another) to create sucessful architectures. SAF include seven activities (maybe I should have called them "the 7 steps program to healthy architecture" :-) ):
- Identifies Stakeholders
- Lists Principles, goals, and constraints
- Discovers quality Attributes
- Models
- Maps to technology
- Evaluates
- Deploys
Again, you can read the complete article online here at DDJ.
Posted by Arnon Rotem-Gal-Oz at 02:55 AM Permalink
|
September 12, 2006
The Software Architecture Document
On the previous post I pointed out some of the possible stakeholders who would be interested in a software architecture document (SAD). In this post, I talk a little about the structure for such a document.
The first thing that should be clear that (unless it is a specific requirement by the client) is that writing a SAD is not a goal in itself. It should be a useful document or it will end right there in the big pile of write-only-documents -- which means it was a waste of time. Take a look at Scott Ambler's essay on "Agile Documentation". I would suggest following these guidelines on both small and large projects.
The second thing to keep in mind is that a SAD is not the place to dump all the output that your {insert favorite case tool here} can generate (and/or reverse engineer). Putting everything in the SAD is just another way to make it, yes you've guessed it--a write-only-document.
The third thing to keep in mind is that you don't have to make the SAD overly formal, the formality level should be driven by customer requirements otherwise just make it useful. (yes I know it is re-iterating the first rule -- but it is important)
The questions is, of course, how do you make it useful?
The key issue here is know who you are writing it for. Since the SAD has many potential readers, a SAD document needs to have several views. Each view can cater to the need of specific stakeholders from their specific viewpoint (IEEE standard 1471-2000 "IEEE Recommended Practice for Architectural Description of Software-Intensive Systems" has a nice and useful model that defines the relations between stakeholders and the architecture documentation). One useful thing you can do is to develop a catalog of useful views and then when the need arise draw on that catalog. RUP offers four views (Process, Logical, Development, physical, plus one on requirements), RM-ODP offers five views (computational, Technology, engineering, information, and enterprise), Zachman has 36 views (I am not going to list them all) , FEAF has 15 etc. One conclusion we can have is that views are indeed, very popular. For us, these are just list of possible views to consider when we need to document something for a stakeholder.
While the list of views is dynamic and optional, one chapter I almost always have is "Rationale, Background and Constraints" this chapter includes:
- Architecture Principles. A few easy to remember guidelines for the architecture including rationale and trade-offs.
- Constraints. Any constraints placed by stakeholders (technological or otherwise), including rationale and implications.
- Utility Tree. Quality attributes and scenarios for the architecture.
- Architecture Overview. A high-level overview of the architecture (main layers, components, relations) and key alternatives (if applicable).
- Future Growth. Expected extension points.
While all this sounds very formal (and it usually is (since I work with clients who usually demand formal
documentation and I still try to keep it concise ) I again remind you that the SAD need not be too formal or to picky in regard to what gets documented . Also remember that maintaining documentation up-to-date is costly only so only document the bare minimum that is useful.
P.S. Two good books that discuss the issues of documenting software architectures are:
Posted by Arnon Rotem-Gal-Oz at 06:20 AM Permalink
|
September 08, 2006
Who Needs a "Software Architecture Document"?
You architected your best solution ever. You have a dozen prototypes to prove your points. You've prepared an architectural skeleton that shows how things work together end-to-end and maybe a few recipes to show developers how to implement important "stuff". Is that enough?
Well, sometimes it can be enough, but often it isn't. The main reason it might not be enough is that the developers are not the only stakeholders interested in the architecture who need to understand the architecture. Who are the stakeholders that may need a software architecture document? They include:
- Project newcomers. The developers already on the team live the architecture and the design. Newcomers need some "signposts" to help them discern what's important and what's not.
- Maintainers. Like project newcomers they need a good guide to help them along. The also need to understand the environment that the development team used (what version of Eclipse, which version of Tibco EMS, do they need Spring? etc.).
- Your replacement (the person who will inherit the project when you move to a better job). She will need more than just signposts. She would also need to understand the rationale behind the decisions you've made.
- System engineers in multi-disciplined projects. The system engineers need to gain some understanding on the architecture (mostly deployment diagrams but they can also be interested in security or safety views of the systems).
- IT team--client's or in-house. They need to understand the implications of the system (deployment/components, security). They need to understand the "what."
- Technical representatives of the client. They need to understand the overall picture, how the solution takes care of the major quality attributes (how do you handle that 1million hits per hour requirement?). Rationale for decisions, options you didn't choose, etc.
- Client . Clients are usually not technical people, but they might want to see that their core requirements are somehow addressed.
- Developers. Sometimes they'll also want to have a document as reference for important decisions.
Occasionally an architecture document is a requirement by the customer. When you decide you need one or when the customer wants you to write one, there are several things you need to watch for to make sure that the software architecture document is useful and doesn't turn into a write-only document. I'll talk about a few of these concerns on the next post.
Posted by Arnon Rotem-Gal-Oz at 06:07 AM Permalink
|
September 05, 2006
Off Topic: Use Case Modeling Article
Dr. Dobb's together with RavenFlow has begun a special, six-issue e-zine called Dr. Dobb's Requirements Development. I am happy to say that the premier issue includes the first installment of a two-part article I wrote entitled "Use Case-Based Requirements," in which I examine the challenges that use case requirements present, then show how to model the use case process.
The issue also includes:
You can get the e-zine by registering on www.ravenflow.com to the bi-monthly Requirements Development magazine.
P.S.
As you may have noticed, all the other article authors have written at least one book. I am working to fill this gap by writing a book on SOA patterns and anti-patterns. (You can see a sample pattern here.) However, as I've only just begun (finishing Chapter 1 as we speak), it will be some time before the book will see the light.
Posted by Arnon Rotem-Gal-Oz at 06:26 PM Permalink
|
September 04, 2006
Overdesign vs. Too Simplistic Design
I recently read David Hyden's blog "Over-Architecting Via Pure Fabrication and Indirection to Reduce Coupling". David explains why he thinks I have learned to see the low coupling principle as an "evil" principle which causes you to add excess levels of indirection in the name of low coupling you rarely need.
I agree you don't want to over engineer for some unknown future (which may never come). That is what YAGNI is all about. However as I said in that and in the JEDUF post, you don't have to look at any problem as if you've never seen anything like it. Your past experience can tell you when some "for future use" feature is more likely than not to be needed. This can even happen (and usually does) within the same project; for example, you have two data entry modules that implement some UI behavior. I would think you would want to use a similar design for both.
Also you need to consider that software--at least successful software--spends most of its time in maintenance and not in development. you want to consider (again, experience can play an important part here) extension points that are likely to be used (Unless, maybe you are going to make a fortune handling all those change requests)
As far as low coupling goes, it is more important at the component or service level (versus the objects level). Nevertheless it doesn't always cost you that much more to add it. Even more important is the fact the lower coupling increases testability. Objects that only depend on abstractions and use dependency injection can be tested in isolation (using mock objects, for example); also see my blog on DI and TDD.
I also think that sometimes the costs of refactoring a solution down the road when you have a lot of behavior to preserve can cost you more that it would to take care of that something at the beginning.
One thing we used successfully in one project is to think out the design for future needs, document it somewhere (e.g. a software architecture document), and then only implement part of the solution to be able to answer the current needs. The advantage here is the the code remains simple for as long as needed but you already know how enhance it when it will be needed. This is especially useful when you have a set of things which are similar in concept but have varying levels of complexity. For example, on one project we have one service that has a very high call load and another that is only invoked occasionally. We designed one pattern for the maximal case and only implemented a partial solution (e.g. we don't have a queue between the edge and the service) for the low-intensity service.
Following the OO principles, adding levels of indirection, and deciding when to design ahead are not always easy--far from it. There's a lot of grey area where principles sometimes pull in different directions (i.e., contradict each other). I don't have some magic formula to say what is right. Experience helps and so does having more than one person look at a design. Nevertheless, the thing that probably helps most is applying common sense.
Posted by Arnon Rotem-Gal-Oz at 08:54 AM Permalink
|
September 01, 2006
Response to Comments on "Strategic Thinking"
I've had a couple of comments on my Strategic Thinking post.
Philip Turner thinks that the definition for stratgic is lacking, or in his words:
The definition of the Strategic Thinking soft skill offered in the article is OK, but it misses the distinctive quality of Strategic Thinking. Namely, strategic thinking is marked by beginning with a focus on the Vision and Objectives for the future and then works backwards to the present situation. Of course, this future vision needs to "understand the industry, market, customers, competitors, suppliers, partners and capabilities of the business. Identifies opportunities and threats, and actively identifies trends and future scenarios" among other things. But, most especially, it needs to start from a shared vision of who the the business aspires to become.
Philip is right, of course. However, architects don't not need that kind of strategic thinking -- that is (hopefully) what the CEO does. Architects need to understand where the CEO is going and enable the enterprise getting there.
Lou Hoebel makes several claims. One is that leadership and strategic thinking are not really needed:
...The reason is that we don't understand the problem and we don't understand the solution space. We won't even see it when it comes. This post actually places additional blinders, process blinders, on the subject my taking a progressive and incremental step but in the wrong direction. Yes, we need leaders and we need strategic thinkers, but they will only help us win the last battle and not the next battle...
I don't really agree with this. As I said in the reply above for Philip, I am not talking here about painting the strategic vision for the business, but I am talking about understanding where it is going. Regarding understanding the problem and the solution spaces -- that's where System Thinking Skills come into play. Regarding leadership, this is a must for architects. As I said in the leadership post , the architect (usually) doesn't have direct authrity (and even if she does without leadership it doesn't mean much). Architects must be able to make other people on the team follow the architecture they design, otherwise it is just useless drawings.
The other claim Lou makes is that the IT and the business are two systems that co-evolve side by side and there is not translation process of business to technology:
In software development we need to understand the key nature of the evolutionary way in which complex software system behave in terms of development, infrastructure, UI and computation. THE first key is this notion of how business and IT align. I posit it to be at the business service and information service layers and interactions. There is no translation process of Business to Technology to which this otherwise useful post alludes. Rather there is a co-evolution of two dynamical systems. So, as interesting as the topic of strategic thinking is in relation to software architects, the definition offered from Bredemeyer is the wrong starting place and perhaps a fatal flaw.
You cannot understand the " … industry, market, customers, competitors, suppliers, partners and capabilities of the business …" and then identify trends. You can only design and construct systems that live in a non-equilibrium infrastructure (SOAs, Infospheres, mashups and the like) and evolve over time as the industry, customers, businesses etc all evolve over time.
I never claimed there was a prescribed process to translate business into IT and I do agree that both IT and the business co-evolve. However my position is that if the architect in charge of the evolution of the IT side doesn't understand where the business is going -- this is a very slim chance -- this co-evolution will be aligned. The fact that there is not prescribed process means that architects cannot just follow some rules to magically obtain this alignment and that they have to think in order to make it a reality. This thinking is the strategic thinking I expect the architect to have.
Posted by Arnon Rotem-Gal-Oz at 05:12 AM Permalink
|
|