윈도우 앱개발을 향하여

블로그 이미지
윈도우 10 스토어에 앱을 개발해 올리는 것을 목표로 하고 있습니다. 비전공자가 독학으로 시도하는 일이어서 얼마나 걸릴지 모르겠지만... 아무튼 목표는 그렇습니다!!
by 코딩하는 경제학도
  • Total hit
  • Today hit
  • Yesterday hit

Copyright

이 모든 내용은 Pluralsight에 Dino Esposito가 올린 'Modern Software Architecture: Domain Models, CQRS, and Event Sourcing'라는 강의의 마지막 챕터를 듣고 정리한 것입니다(https://app.pluralsight.com/library/courses/modern-software-architecture-domain-models-cqrs-event-sourcing/table-of-contents). 강의 원작자분께 게시허가도 받았습니다.


Content

Discovering the Domain Architecture through DDD

The DDD Layered Architecture

The "Domain Model" Supporting Architecture

The CQRS Supporting Architecture

Event Sourcing

Designing Software Driven by the Domain


Outline

Dealing with Legacy Code

Revisiting CRUD Systems

UX-drive design

Pillars of Modern Software



Dealing with Legacy Code

There are many known ways to define legacy code. Often by legacy code we mean code that exists that some other people wrote and that is complex and undocumented enough that everybody is scared to touch. Legacy code is primarily code that just works. It might not be doing things in the most appropriate way for the current needs of the business, so you feel like it has to be properly refactored and possibly rewritten. In other words, you don't like to have it around. But because it works and because everybody is constantly late on something, there is never time to do it, and in the end, you can hardly get rid of it.


However, sometimes what we call legacy code is not necessarily badly and poorly written code. Sometimes it's just coded now for the current state of the business should be doing additional things or differently. But for a number of reasons, it's risky to touch it, or it just takes time because of the complexity it carries.


Common Aspects of Legacy Code

Has an established and implicit model

Doesn't typically have a public programmable API

Written to have some work done, not to be reused

Written years ago according to practices now obsolete


How to incorporate legacy code in new applications? 

My favorite approach is trying to expose the legacy code as a service if all possible. If not, I would seriously consider rewriting. But this is just a general guideline I use, but in the end, it always depends case by case.


Legacy Code as a Service

So I'd say you start with the idea of rewriting the system and get all the abstractions you need. If some features you need to rewrite then exist in the legacy system, I'd consider incorporating existing assets as services rather than rewriting everything from scratch. Needless to say, this only works if the new system you need has exactly the same features and the same behavior. If you can disconnect the legacy code and recompile it as an independent piece of code, then put it in a bounded context, expose it as a service, and create a façade around it to make it work with the rest of the new system. It may not work, but if it works, it's just great.


Not because you can do something, you should be doing that particular thing.

Not all legacy assets are equal. Some can be reused as services, some not. Some are just old and obsolete.

Before integrating legacy code, make sure you carefully evaluate the costs of not rewriting from scratch and also the costs of integrating legacy code as a service. Next, if legacy code can be turned into a service, then just let it be and focus on other things to do.



Revisiting CRUD Systems

CRUD is a long-time popular acronym to indicate a system that focuses on four fundamental operations in relationship to both the user interface and storage, create, read or retrieve, update, and delete. In this regard, it's essentially correct to state that all systems are CRUD systems at least to some extent.


The CRUD cycle describes the core functions of a persistent database, typically a relational database. The code implements the CREATE, READ, UPDATE, and DELETE operations, and saves the resulting state to the database. While it's probably correct to state that merely all systems are CRUD to some extent, the devil is in the details of what actually turns out to be the object of those operations. Is it a single individual entity or is it a more complex and articulated data representation? Let's try to list a few common attributes of a CRUD system.


First and foremost, a CRUD system is database-centric. The model of data available to the code is exactly the same being persisted. Deletions and updates affect directly the data stored. This means that at any time you know the current state, but you are not tracking what has really happened. A CRUD system for the most part has relatively basic business logic and is being used by one or very few users and deals with very elemental collections of data, mostly one-to-one with database tables. In summary, a CRUD is typically quick and easy to write and subsequently it often looks unrealistic these days.


When we hear or pronounce the words it's basically a CRUD, we are right in that we want the four basic operations being implemented. But tracking actions or not, the amount of business logic and rules, concurrency and dependencies between data entities change significantly the scope of the system and raise significantly the level of complexity and effort. So it's basically a CRUD system, but must be devised in quite a different way to be realistic and effective as of today.


Sure, a CRUD system is database-centric. In modern software, however, that persistence model is just one model to think about. Sometimes to better process relationships between collections of data, you need to build a different model that expresses behavior while saving state or just actions through a different model. More often than not, the context of change must be tracked. An update cannot simply be overriding the current state of a given record. It might be necessary that it's tracked whether it is an update to the state, tracking to delta, and all of them in the life of a data entity. Plenty of business logic, concurrency issues, and interconnected entities, graphs of objects populate the modern software and systems must take that into account.


So, we still have CRUD operations against a database, but CREATE deals with graphs of entities, READ fills out views, UPDATE and DELETE log the change to the current state of the system, and today, C, U, and D, CREATE, UPDATE, and DELETE are commands and reads, the R, are queries, and this why the CQRS approach is vital and fundamental for today's applications.



UX-drive design

What you see is what you get is an old slogan of the graphical user interfaces of development tools like Visual Basic, but what you see is what you get is also today a philosophy we can apply to software architecture. What users perceive of each application is what they see(User Interface) and what they get(User Experience) as they interact with the application. #The user experience is the experience that users go through when they interact with a given application.


In light of the user experience, Top-down approach is more effective way to architect a system then the bottom-up approach. The bottom-up approach to software architecture is based on the idea that you understand requirements and start building the foundation of the system from the persistence model. Your foundation is a layer of data with some endpoints that are looking for an outlet. As long as users are passively accepting any UI enforcements. But now more and more users are actively dictating user interface and user experience preferences. Therefore, you'd better start designing from some front-end they like. Endpoints to connect to the rest of the system are exposed from the presentation layer and the rest of the system is then designed just to match those endpoints. And persistence is designed to save data you need to save in the shape that data counts your way down the stacks. In the end, it is presentation and everything else is sort of a big black box.


The whole point of top-down design is making sure that you are going to produce a set of screens and an overall user experience that fully matches user expectations. Performance and even business logic can be fixed and fine-tuned, but if you miss the user experience, customers may have to alter the way they do business and go through their tasks. It may not be ideal.


UX-driven Design in 3 Steps

1. Building up UI forms and screens as users love them

You can use Y frames and Y framing tools for this purpose. At this point, once screens have been approved, you have a complete list of triggers that can start any business process.

2. Implement workflows and bind workflows to presentation endpoints

3. A workflow represents a business process and you create old layers that need be there

repositories, domain services, whatever else that serves the purpose of implementing successfully the business process


For the whole method to work, however, it's key that you hold on and iterate on the UI forms approval process(step 1) until you get users signing off approving explicitly. And when they say yes only then you proceed. Any time you appear to waste, this stage is saved later by not likely having to restructure the code because of a poor or wrong user experience.


In summary, sign off on what users want and use sketches and Y frames to get their approval. A sketch is a freehand drawing mostly made to capture an idea. A wireframe is a more sophisticated sketch with layout navigation and content information. The point is avoid doing any seriously billable work until you are certain about the front-end of what you're going to create.


More in detail, UX driven designs suggest you have a basic flowchart for each screen

Determine what comes in and out of each screen and create view-model classes

Make application layer endpoints receive and return such DTO(data transfer object) classes

Make application layer orchestrate tasks on layers down the stack

So repositories, domain services, external services, and whatever else you may need to set up and work with


Responsibilities of the UX Architect

Defining the information architecture and content layout

Defining the ideal interaction, which means essentially storyboards for each screen and each UI trigger

Being around the definition of the visual design

Running usability reviews


Tools for the UX Architect

Balsamiq, UXPin, Infragistics Indigo, JustInMind


UX Architect in the end is only a role and the same individual can be at the same time acting as the UX and/or the solution software architect.



Pillars of Modern Software

A few final words about the state of the art of today's software architecture then are in order.



First, the definition of domain-driven design should be revisited to add emphasis on the tools for domain analysis, such as ubiquitous language, bounded contexts, and context maps.


Second, in the building of each bounded context, the layer the architecture is key to having best of breed today layers over tiers are preferable as scalability these days can easily be achieved, obtained with a stateless single tier, small, compact, simple servers, implemented perhaps as web roles in some Cloud platform and then scaled according to the dashboard and the rules and the possibilities of the Cloud platform.


Third, the design of systems should be top-down, as it starts from what users really want and expect. This means great user experience by design and built from the ground up.


Finally, to achieve everything to build actual back-end of the system, CQRS command and query responsibilities, segregation, and event sourcing are the new and important hot things. These days separating command and query stacks makes everything in the building of the application more natural, convenient, and simple to code, and even simple to optimize, because the stacks are separated and the command part and the query part can be deployed and optimized without effecting each other. Event-based persistence, yet another cool aspect of modern software architecture, lets you not miss a thing and makes the entire solution subsequently easy to extend in the future by adding more features and supporting more notifications, more commands, and subsequently, more events. 



출처

이 모든 내용은 Pluralsight에 Dino Esposito가 올린 'Modern Software Architecture: Domain Models, CQRS, and Event Sourcing'라는 강의의 마지막 챕터를 듣고 정리한 것입니다(https://app.pluralsight.com/library/courses/modern-software-architecture-domain-models-cqrs-event-sourcing/table-of-contents). 제가 정리한 것보다 더 많은 내용과 Demo를 포함하고 있으며 최종 Summary는 생략하겠습니다. Microsoft 지원을 통해 한달간 무료로 Pluralsight의 강의를 들으실 수도 있습니다.

AND

ARTICLE CATEGORY

분류 전체보기 (56)
Programming (45)
MSDN (4)
개발노트 (2)
reference (5)

RECENT ARTICLE

RECENT COMMENT

CALENDAR

«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

ARCHIVE